This source file includes following definitions.
- ftdm_channel_get_session
- ftdm_channel_get_uuid
- stop_hold
- start_hold
- cycle_foreground
- tech_init
- channel_on_init
- channel_on_routing
- channel_on_execute
- channel_on_destroy
- channel_on_hangup
- channel_kill_channel
- channel_on_exchange_media
- channel_on_soft_execute
- channel_send_dtmf
- channel_read_frame
- channel_write_frame
- channel_receive_message_cas
- channel_receive_message_b
- channel_receive_message_fxo
- channel_receive_message_fxs
- channel_receive_message
- channel_outgoing_channel
- ftdm_channel_from_event
- FIO_SIGNAL_CB_FUNCTION
- ftdm_enable_channel_dtmf
- FIO_SIGNAL_CB_FUNCTION
- FIO_SIGNAL_CB_FUNCTION
- FIO_SIGNAL_CB_FUNCTION
- FIO_SIGNAL_CB_FUNCTION
- FIO_SIGNAL_CB_FUNCTION
- ftdm_logger
- enable_analog_option
- add_config_list_nodes
- get_ss7_config_node
- add_profile_parameters
- parse_bri_pri_spans
- load_config
- dump_chan
- dump_chan_xml
- SWITCH_STANDARD_API
- SWITCH_STANDARD_APP
- SWITCH_STANDARD_APP
- SWITCH_STANDARD_APP
- SWITCH_MODULE_LOAD_FUNCTION
- SWITCH_MODULE_SHUTDOWN_FUNCTION
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <switch.h>
35 #include "freetdm.h"
36
37 #ifndef __FUNCTION__
38 #define __FUNCTION__ __SWITCH_FUNC__
39 #endif
40
41 #define FREETDM_LIMIT_REALM "__freetdm"
42 #define FREETDM_VAR_PREFIX "freetdm_"
43 #define FREETDM_VAR_PREFIX_LEN (sizeof(FREETDM_VAR_PREFIX)-1)
44
45 SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load);
46 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_freetdm_shutdown);
47 SWITCH_MODULE_DEFINITION(mod_freetdm, mod_freetdm_load, mod_freetdm_shutdown, NULL);
48
49 switch_endpoint_interface_t *freetdm_endpoint_interface;
50
51 static switch_memory_pool_t *module_pool = NULL;
52
53 typedef enum {
54 ANALOG_OPTION_NONE = 0,
55 ANALOG_OPTION_3WAY = (1 << 0),
56 ANALOG_OPTION_CALL_SWAP = (1 << 1)
57 } analog_option_t;
58
59 typedef enum {
60 FTDM_LIMIT_RESET_ON_TIMEOUT = 0,
61 FTDM_LIMIT_RESET_ON_ANSWER = 1
62 } limit_reset_event_t;
63
64 typedef enum {
65 TFLAG_IO = (1 << 0),
66 TFLAG_DTMF = (1 << 1),
67 TFLAG_CODEC = (1 << 2),
68 TFLAG_BREAK = (1 << 3),
69 TFLAG_HOLD = (1 << 4),
70 TFLAG_DEAD = (1 << 5)
71 } TFLAGS;
72
73 static struct {
74 int debug;
75 char *dialplan;
76 char *codec_string;
77 char *codec_order[SWITCH_MAX_CODECS];
78 int codec_order_last;
79 char *codec_rates_string;
80 char *codec_rates[SWITCH_MAX_CODECS];
81 int codec_rates_last;
82 unsigned int flags;
83 int fd;
84 int calls;
85 char hold_music[256];
86 switch_mutex_t *mutex;
87 analog_option_t analog_options;
88 switch_hash_t *ss7_configs;
89 int sip_headers;
90 uint8_t crash_on_assert;
91 } globals;
92
93
94 struct private_object {
95 unsigned int flags;
96 switch_codec_t read_codec;
97 switch_codec_t write_codec;
98 switch_frame_t read_frame;
99 unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
100 switch_frame_t cng_frame;
101 unsigned char cng_databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
102 switch_core_session_t *session;
103 switch_caller_profile_t *caller_profile;
104 unsigned int codec;
105 unsigned int codecs;
106 unsigned short samprate;
107 switch_mutex_t *mutex;
108 switch_mutex_t *flag_mutex;
109 ftdm_channel_t *ftdmchan;
110 uint32_t wr_error;
111 };
112
113
114 typedef struct chan_pvt {
115 unsigned int flags;
116 } chan_pvt_t;
117
118 typedef struct private_object private_t;
119
120 struct span_config {
121 ftdm_span_t *span;
122 char dialplan[80];
123 char context[80];
124 char dial_regex[256];
125 char fail_dial_regex[256];
126 char hold_music[256];
127 char type[256];
128 analog_option_t analog_options;
129 const char *limit_backend;
130 int limit_calls;
131 int limit_seconds;
132 limit_reset_event_t limit_reset_event;
133 chan_pvt_t pvts[FTDM_MAX_CHANNELS_SPAN];
134 };
135
136 static struct span_config SPAN_CONFIG[FTDM_MAX_SPANS_INTERFACE] = {{0}};
137
138 static switch_status_t channel_on_init(switch_core_session_t *session);
139 static switch_status_t channel_on_hangup(switch_core_session_t *session);
140 static switch_status_t channel_on_destroy(switch_core_session_t *session);
141 static switch_status_t channel_on_routing(switch_core_session_t *session);
142 static switch_status_t channel_on_exchange_media(switch_core_session_t *session);
143 static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
144 static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
145 switch_caller_profile_t *outbound_profile,
146 switch_core_session_t **new_session,
147 switch_memory_pool_t **pool,
148 switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
149 static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
150 static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
151 static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
152 ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session_t **sp);
153 void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream);
154 void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream);
155
156 static switch_core_session_t *ftdm_channel_get_session(ftdm_channel_t *channel, int32_t id)
157 {
158 switch_core_session_t *session = NULL;
159 const char *token = ftdm_channel_get_token(channel, id);
160
161 if (!zstr(token)) {
162 if (!(session = switch_core_session_locate(token))) {
163 ftdm_channel_clear_token(channel, token);
164 }
165 }
166
167 return session;
168 }
169
170 static const char *ftdm_channel_get_uuid(ftdm_channel_t *channel, int32_t id)
171 {
172 return ftdm_channel_get_token(channel, id);
173 }
174
175 static void stop_hold(switch_core_session_t *session_a, const char *uuid)
176 {
177 switch_core_session_t *session;
178 switch_channel_t *channel, *channel_a;
179 ;
180
181 if (!uuid) {
182 return;
183 }
184
185 if ((session = switch_core_session_locate(uuid))) {
186 channel = switch_core_session_get_channel(session);
187
188 if (switch_channel_test_flag(channel, CF_HOLD)) {
189 channel_a = switch_core_session_get_channel(session_a);
190 switch_ivr_unhold(session);
191 switch_channel_clear_flag(channel_a, CF_SUSPEND);
192 switch_channel_clear_flag(channel_a, CF_HOLD);
193 } else {
194 switch_channel_stop_broadcast(channel);
195 switch_channel_wait_for_flag(channel, CF_BROADCAST, SWITCH_FALSE, 2000, NULL);
196 }
197
198 switch_core_session_rwunlock(session);
199 }
200 }
201
202 static void start_hold(ftdm_channel_t *ftdmchan, switch_core_session_t *session_a, const char *uuid, const char *stream)
203 {
204 switch_core_session_t *session;
205 switch_channel_t *channel, *channel_a;
206 int32_t spanid = 0;
207
208 if (!uuid) {
209 return;
210 }
211
212 spanid = ftdm_channel_get_span_id(ftdmchan);
213 if ((session = switch_core_session_locate(uuid))) {
214 channel = switch_core_session_get_channel(session);
215 if (zstr(stream)) {
216 if (!strcasecmp(globals.hold_music, "indicate_hold")) {
217 stream = "indicate_hold";
218 }
219 if (!strcasecmp(SPAN_CONFIG[spanid].hold_music, "indicate_hold")) {
220 stream = "indicate_hold";
221 }
222 }
223
224 if (zstr(stream)) {
225 stream = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE);
226 }
227
228 if (zstr(stream)) {
229 stream = SPAN_CONFIG[spanid].hold_music;
230 }
231
232 if (zstr(stream)) {
233 stream = globals.hold_music;
234 }
235
236
237 if (zstr(stream) && !(stream = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE))) {
238 stream = globals.hold_music;
239 }
240
241 if (!zstr(stream)) {
242 if (!strcasecmp(stream, "indicate_hold")) {
243 channel_a = switch_core_session_get_channel(session_a);
244 switch_ivr_hold_uuid(uuid, NULL, 0);
245 switch_channel_set_flag(channel_a, CF_SUSPEND);
246 switch_channel_set_flag(channel_a, CF_HOLD);
247 } else {
248 switch_ivr_broadcast(switch_core_session_get_uuid(session), stream, SMF_ECHO_ALEG | SMF_LOOP);
249 }
250 }
251
252 switch_core_session_rwunlock(session);
253 }
254 }
255
256
257 static void cycle_foreground(ftdm_channel_t *ftdmchan, int flash, const char *bcast) {
258 uint32_t i = 0;
259 switch_core_session_t *session;
260 switch_channel_t *channel;
261 private_t *tech_pvt;
262 uint32_t tokencnt = ftdm_channel_get_token_count(ftdmchan);
263
264
265 for (i = 0; i < tokencnt; i++) {
266 if ((session = ftdm_channel_get_session(ftdmchan, i))) {
267 const char *buuid;
268 tech_pvt = switch_core_session_get_private(session);
269 channel = switch_core_session_get_channel(session);
270 buuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE);
271
272
273 if (tokencnt == 1 && flash) {
274 if (switch_test_flag(tech_pvt, TFLAG_HOLD)) {
275 stop_hold(session, buuid);
276 switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
277 } else {
278 start_hold(ftdmchan, session, buuid, bcast);
279 switch_set_flag_locked(tech_pvt, TFLAG_HOLD);
280 }
281 } else if (i) {
282 start_hold(ftdmchan, session, buuid, bcast);
283 switch_set_flag_locked(tech_pvt, TFLAG_HOLD);
284 } else {
285 stop_hold(session, buuid);
286 switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
287 if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
288 switch_channel_mark_answered(channel);
289 }
290 }
291 switch_core_session_rwunlock(session);
292 }
293 }
294 }
295
296
297
298
299 static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *session, ftdm_channel_t *ftdmchan)
300 {
301 const char *dname = NULL;
302 uint32_t interval = 0, srate = 8000;
303 ftdm_codec_t codec;
304
305 tech_pvt->ftdmchan = ftdmchan;
306 tech_pvt->read_frame.data = tech_pvt->databuf;
307 tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
308 tech_pvt->cng_frame.data = tech_pvt->cng_databuf;
309 tech_pvt->cng_frame.buflen = sizeof(tech_pvt->cng_databuf);
310 tech_pvt->cng_frame.flags = SFF_CNG;
311 tech_pvt->cng_frame.codec = &tech_pvt->read_codec;
312 memset(tech_pvt->cng_frame.data, 255, tech_pvt->cng_frame.buflen);
313 switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
314 switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
315 switch_core_session_set_private(session, tech_pvt);
316 tech_pvt->session = session;
317
318 if (FTDM_SUCCESS != ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval)) {
319 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel interval.\n");
320 return SWITCH_STATUS_GENERR;
321 }
322
323 if (FTDM_SUCCESS != ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_CODEC, &codec)) {
324 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel codec.\n");
325 return SWITCH_STATUS_GENERR;
326 }
327
328 switch(codec) {
329 case FTDM_CODEC_ULAW:
330 {
331 dname = "PCMU";
332 }
333 break;
334 case FTDM_CODEC_ALAW:
335 {
336 dname = "PCMA";
337 }
338 break;
339 case FTDM_CODEC_SLIN:
340 {
341 dname = "L16";
342 }
343 break;
344 default:
345 {
346 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid codec value retrieved from channel, codec value: %d\n", codec);
347 return SWITCH_STATUS_GENERR;
348 }
349 }
350
351
352 if (switch_core_codec_init(&tech_pvt->read_codec,
353 dname,
354 NULL,
355 srate,
356 interval,
357 1,
358 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
359 NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
360 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
361 return SWITCH_STATUS_GENERR;
362 } else {
363 if (switch_core_codec_init(&tech_pvt->write_codec,
364 dname,
365 NULL,
366 srate,
367 interval,
368 1,
369 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
370 NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
371 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
372 switch_core_codec_destroy(&tech_pvt->read_codec);
373 return SWITCH_STATUS_GENERR;
374 }
375 }
376
377 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set codec %s %dms\n", dname, interval);
378 switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
379 switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
380 switch_set_flag_locked(tech_pvt, TFLAG_CODEC);
381 tech_pvt->read_frame.codec = &tech_pvt->read_codec;
382 switch_set_flag_locked(tech_pvt, TFLAG_IO);
383
384 return SWITCH_STATUS_SUCCESS;
385
386 }
387
388 static switch_status_t channel_on_init(switch_core_session_t *session)
389 {
390 switch_channel_t *channel;
391 private_t *tech_pvt = NULL;
392
393 tech_pvt = switch_core_session_get_private(session);
394 assert(tech_pvt != NULL);
395
396 channel = switch_core_session_get_channel(session);
397 assert(channel != NULL);
398
399 if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
400 switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
401 return SWITCH_STATUS_SUCCESS;
402 }
403
404
405 switch_channel_set_state(channel, CS_ROUTING);
406 switch_mutex_lock(globals.mutex);
407 globals.calls++;
408 switch_mutex_unlock(globals.mutex);
409
410 ftdm_channel_init(tech_pvt->ftdmchan);
411
412
413
414 return SWITCH_STATUS_SUCCESS;
415 }
416
417 static switch_status_t channel_on_routing(switch_core_session_t *session)
418 {
419 switch_channel_t *channel = NULL;
420 private_t *tech_pvt = NULL;
421
422 channel = switch_core_session_get_channel(session);
423 assert(channel != NULL);
424
425 tech_pvt = switch_core_session_get_private(session);
426 assert(tech_pvt != NULL);
427
428 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel));
429
430 return SWITCH_STATUS_SUCCESS;
431 }
432
433 static switch_status_t channel_on_execute(switch_core_session_t *session)
434 {
435
436 switch_channel_t *channel = NULL;
437 private_t *tech_pvt = NULL;
438
439 channel = switch_core_session_get_channel(session);
440 assert(channel != NULL);
441
442 tech_pvt = switch_core_session_get_private(session);
443 assert(tech_pvt != NULL);
444
445 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));
446
447
448 return SWITCH_STATUS_SUCCESS;
449 }
450
451 static switch_status_t channel_on_destroy(switch_core_session_t *session)
452 {
453 private_t *tech_pvt = NULL;
454
455 if ((tech_pvt = switch_core_session_get_private(session))) {
456
457 if (tech_pvt->read_codec.implementation) {
458 switch_core_codec_destroy(&tech_pvt->read_codec);
459 }
460
461 if (tech_pvt->write_codec.implementation) {
462 switch_core_codec_destroy(&tech_pvt->write_codec);
463 }
464 }
465
466 return SWITCH_STATUS_SUCCESS;
467 }
468
469 static switch_status_t channel_on_hangup(switch_core_session_t *session)
470 {
471 switch_channel_t *channel = NULL;
472 private_t *tech_pvt = NULL;
473 ftdm_chan_type_t chantype;
474 uint32_t tokencnt;
475
476 channel = switch_core_session_get_channel(session);
477 assert(channel != NULL);
478
479 tech_pvt = switch_core_session_get_private(session);
480 assert(tech_pvt != NULL);
481
482 if (!tech_pvt->ftdmchan) {
483 goto end;
484 }
485
486 ftdm_channel_clear_token(tech_pvt->ftdmchan, switch_core_session_get_uuid(session));
487
488 chantype = ftdm_channel_get_type(tech_pvt->ftdmchan);
489 switch (chantype) {
490 case FTDM_CHAN_TYPE_FXO:
491 case FTDM_CHAN_TYPE_EM:
492 case FTDM_CHAN_TYPE_CAS:
493 {
494 ftdm_channel_call_hangup(tech_pvt->ftdmchan);
495 }
496 break;
497 case FTDM_CHAN_TYPE_FXS:
498 {
499 if (!ftdm_channel_call_check_busy(tech_pvt->ftdmchan) && !ftdm_channel_call_check_done(tech_pvt->ftdmchan)) {
500 tokencnt = ftdm_channel_get_token_count(tech_pvt->ftdmchan);
501 if (tokencnt) {
502 cycle_foreground(tech_pvt->ftdmchan, 0, NULL);
503 } else {
504 ftdm_channel_call_hangup(tech_pvt->ftdmchan);
505 }
506 }
507 }
508 break;
509 case FTDM_CHAN_TYPE_B:
510 {
511 ftdm_call_cause_t hcause = switch_channel_get_cause_q850(channel);
512 if (hcause < 1 || hcause > 127) {
513 hcause = FTDM_CAUSE_DESTINATION_OUT_OF_ORDER;
514 }
515 ftdm_channel_call_hangup_with_cause(tech_pvt->ftdmchan, hcause);
516 }
517 break;
518 default:
519 {
520 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unhandled channel type %d for channel %s\n", chantype,
521 switch_channel_get_name(channel));
522 }
523 break;
524 }
525
526 end:
527
528 switch_clear_flag_locked(tech_pvt, TFLAG_IO);
529
530 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel));
531 switch_mutex_lock(globals.mutex);
532 globals.calls--;
533 if (globals.calls < 0) {
534 globals.calls = 0;
535 }
536 switch_mutex_unlock(globals.mutex);
537
538 return SWITCH_STATUS_SUCCESS;
539 }
540
541 static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig)
542 {
543 switch_channel_t *channel = NULL;
544 private_t *tech_pvt = NULL;
545
546 channel = switch_core_session_get_channel(session);
547 assert(channel != NULL);
548
549 tech_pvt = switch_core_session_get_private(session);
550 assert(tech_pvt != NULL);
551
552 switch (sig) {
553 case SWITCH_SIG_KILL:
554 switch_clear_flag_locked(tech_pvt, TFLAG_IO);
555 switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
556 break;
557 case SWITCH_SIG_BREAK:
558 switch_set_flag_locked(tech_pvt, TFLAG_BREAK);
559 break;
560 default:
561 break;
562 }
563
564 return SWITCH_STATUS_SUCCESS;
565 }
566
567 static switch_status_t channel_on_exchange_media(switch_core_session_t *session)
568 {
569 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL EXCHANGE_MEDIA\n");
570 return SWITCH_STATUS_SUCCESS;
571 }
572
573 static switch_status_t channel_on_soft_execute(switch_core_session_t *session)
574 {
575 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL SOFT_EXECUTE\n");
576 return SWITCH_STATUS_SUCCESS;
577 }
578
579 static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
580 {
581 private_t *tech_pvt = NULL;
582 char tmp[2] = "";
583
584 tech_pvt = switch_core_session_get_private(session);
585 assert(tech_pvt != NULL);
586
587 if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
588 switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE);
589 return SWITCH_STATUS_FALSE;
590 }
591
592 tmp[0] = dtmf->digit;
593 ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_SEND_DTMF, tmp);
594
595 return SWITCH_STATUS_SUCCESS;
596 }
597
598 static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
599 {
600 switch_channel_t *channel = NULL;
601 private_t *tech_pvt = NULL;
602 ftdm_size_t len;
603 ftdm_wait_flag_t wflags = FTDM_READ;
604 char dtmf[128] = "";
605 ftdm_status_t status;
606 int total_to;
607 int chunk, do_break = 0;
608
609
610 channel = switch_core_session_get_channel(session);
611 assert(channel != NULL);
612
613
614 tech_pvt = switch_core_session_get_private(session);
615 assert(tech_pvt != NULL);
616
617 if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
618 ftdm_log(FTDM_LOG_DEBUG, "TFLAG_DEAD is set\n");
619 return SWITCH_STATUS_FALSE;
620 }
621
622
623
624
625 chunk = ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 2;
626 total_to = chunk * 6;
627
628 top:
629
630 if (switch_channel_test_flag(channel, CF_SUSPEND)) {
631 do_break = 1;
632 }
633
634 if (switch_test_flag(tech_pvt, TFLAG_BREAK)) {
635 switch_clear_flag_locked(tech_pvt, TFLAG_BREAK);
636 do_break = 1;
637 }
638
639 if (switch_test_flag(tech_pvt, TFLAG_HOLD) || do_break) {
640 switch_yield(ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 1000);
641 tech_pvt->cng_frame.datalen = ftdm_channel_get_io_packet_len(tech_pvt->ftdmchan);
642 tech_pvt->cng_frame.samples = tech_pvt->cng_frame.datalen;
643 tech_pvt->cng_frame.flags = SFF_CNG;
644 *frame = &tech_pvt->cng_frame;
645 if (ftdm_channel_get_codec(tech_pvt->ftdmchan) == FTDM_CODEC_SLIN) {
646 tech_pvt->cng_frame.samples /= 2;
647 }
648 return SWITCH_STATUS_SUCCESS;
649 }
650
651 if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
652 ftdm_log(FTDM_LOG_DEBUG, "TFLAG_IO is not set\n");
653 goto fail;
654 }
655
656 wflags = FTDM_READ;
657 status = ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, chunk);
658
659 if (status == FTDM_FAIL) {
660 ftdm_log(FTDM_LOG_WARNING, "failed to wait for I/O\n");
661 goto fail;
662 }
663
664 if (status == FTDM_TIMEOUT) {
665 if (!switch_test_flag(tech_pvt, TFLAG_HOLD)) {
666 total_to -= chunk;
667 if (total_to <= 0) {
668 ftdm_log(FTDM_LOG_WARNING, "Too many timeouts while waiting for I/O\n");
669 goto fail;
670 }
671 }
672 goto top;
673 }
674
675 if (!(wflags & FTDM_READ)) {
676 goto top;
677 }
678
679 len = tech_pvt->read_frame.buflen;
680 if (ftdm_channel_read(tech_pvt->ftdmchan, tech_pvt->read_frame.data, &len) != FTDM_SUCCESS) {
681 ftdm_log(FTDM_LOG_WARNING, "failed to read from device\n");
682 goto fail;
683 }
684
685 *frame = &tech_pvt->read_frame;
686 tech_pvt->read_frame.datalen = (uint32_t)len;
687 tech_pvt->read_frame.samples = tech_pvt->read_frame.datalen;
688
689 if (ftdm_channel_get_codec(tech_pvt->ftdmchan) == FTDM_CODEC_SLIN) {
690 tech_pvt->read_frame.samples /= 2;
691 }
692
693 while (ftdm_channel_dequeue_dtmf(tech_pvt->ftdmchan, dtmf, sizeof(dtmf))) {
694 switch_dtmf_t _dtmf = { 0, SWITCH_DEFAULT_DTMF_DURATION };
695 char *p;
696 for (p = dtmf; p && *p; p++) {
697 if (is_dtmf(*p)) {
698 _dtmf.digit = *p;
699 ftdm_log(FTDM_LOG_DEBUG, "Queuing DTMF [%c] in channel %s\n", *p, switch_channel_get_name(channel));
700 switch_channel_queue_dtmf(channel, &_dtmf);
701 }
702 }
703 }
704 return SWITCH_STATUS_SUCCESS;
705
706 fail:
707 switch_clear_flag_locked(tech_pvt, TFLAG_IO);
708 return SWITCH_STATUS_GENERR;
709
710
711 }
712
713 static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
714 {
715 switch_channel_t *channel = NULL;
716 private_t *tech_pvt = NULL;
717 ftdm_size_t len;
718 unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
719 ftdm_wait_flag_t wflags = FTDM_WRITE;
720 ftdm_status_t status;
721
722 channel = switch_core_session_get_channel(session);
723 assert(channel != NULL);
724
725 tech_pvt = switch_core_session_get_private(session);
726 assert(tech_pvt != NULL);
727
728 if (!tech_pvt->ftdmchan) {
729 return SWITCH_STATUS_FALSE;
730 }
731
732 if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
733 return SWITCH_STATUS_FALSE;
734 }
735
736 if (switch_test_flag(tech_pvt, TFLAG_HOLD)) {
737 return SWITCH_STATUS_SUCCESS;
738 }
739
740 if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
741 goto fail;
742 }
743
744 if (switch_test_flag(frame, SFF_CNG)) {
745 frame->data = data;
746 frame->buflen = sizeof(data);
747 if ((frame->datalen = tech_pvt->write_codec.implementation->encoded_bytes_per_packet) > frame->buflen) {
748 goto fail;
749 }
750 memset(data, 255, frame->datalen);
751 }
752
753
754 wflags = FTDM_WRITE;
755 status = ftdm_channel_wait(tech_pvt->ftdmchan, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdmchan) * 10);
756
757 if (!(wflags & FTDM_WRITE)) {
758 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write not ready)\n");
759 return SWITCH_STATUS_SUCCESS;
760 }
761
762 len = frame->datalen;
763 if (ftdm_channel_write(tech_pvt->ftdmchan, frame->data, frame->buflen, &len) != FTDM_SUCCESS) {
764 if (++tech_pvt->wr_error > 10) {
765 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "too many I/O write errors!\n");
766 goto fail;
767 }
768 } else {
769 tech_pvt->wr_error = 0;
770 }
771
772 return SWITCH_STATUS_SUCCESS;
773
774 fail:
775
776 switch_clear_flag_locked(tech_pvt, TFLAG_IO);
777 return SWITCH_STATUS_GENERR;
778
779 }
780
781 static switch_status_t channel_receive_message_cas(switch_core_session_t *session, switch_core_session_message_t *msg)
782 {
783 switch_channel_t *channel;
784 private_t *tech_pvt;
785 uint32_t phy_id;
786
787 channel = switch_core_session_get_channel(session);
788 assert(channel != NULL);
789
790 tech_pvt = (private_t *) switch_core_session_get_private(session);
791 assert(tech_pvt != NULL);
792
793 if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
794 switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
795 return SWITCH_STATUS_FALSE;
796 }
797
798 phy_id = ftdm_channel_get_ph_id(tech_pvt->ftdmchan);
799 ftdm_log(FTDM_LOG_DEBUG, "Got Freeswitch message in R2 channel %d [%d]\n", phy_id, msg->message_id);
800
801 if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
802 return SWITCH_STATUS_SUCCESS;
803 }
804
805 switch (msg->message_id) {
806 case SWITCH_MESSAGE_INDICATE_RINGING:
807 {
808 ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS);
809 }
810 break;
811 case SWITCH_MESSAGE_INDICATE_PROGRESS:
812 {
813 ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA);
814 }
815 break;
816 case SWITCH_MESSAGE_INDICATE_ANSWER:
817 {
818 ftdm_channel_call_answer(tech_pvt->ftdmchan);
819 }
820 break;
821 default:
822 break;
823 }
824
825 return SWITCH_STATUS_SUCCESS;
826 }
827
828 static switch_status_t channel_receive_message_b(switch_core_session_t *session, switch_core_session_message_t *msg)
829 {
830 switch_channel_t *channel;
831 private_t *tech_pvt;
832
833 channel = switch_core_session_get_channel(session);
834 assert(channel != NULL);
835
836 tech_pvt = (private_t *) switch_core_session_get_private(session);
837 assert(tech_pvt != NULL);
838
839 if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
840 switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
841 return SWITCH_STATUS_FALSE;
842 }
843
844 if (ftdm_channel_call_check_hangup(tech_pvt->ftdmchan)) {
845 return SWITCH_STATUS_SUCCESS;
846 }
847
848 if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
849 return SWITCH_STATUS_SUCCESS;
850 }
851
852 switch (msg->message_id) {
853 case SWITCH_MESSAGE_INDICATE_RINGING:
854 {
855 ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS);
856 }
857 break;
858 case SWITCH_MESSAGE_INDICATE_PROGRESS:
859 {
860 ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_PROGRESS_MEDIA);
861 }
862 break;
863 case SWITCH_MESSAGE_INDICATE_ANSWER:
864 {
865 ftdm_channel_call_answer(tech_pvt->ftdmchan);
866 }
867 break;
868 default:
869 break;
870 }
871
872 return SWITCH_STATUS_SUCCESS;
873 }
874
875 static switch_status_t channel_receive_message_fxo(switch_core_session_t *session, switch_core_session_message_t *msg)
876 {
877 switch_channel_t *channel;
878 private_t *tech_pvt;
879
880 channel = switch_core_session_get_channel(session);
881 assert(channel != NULL);
882
883 tech_pvt = (private_t *) switch_core_session_get_private(session);
884 assert(tech_pvt != NULL);
885
886 if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
887 switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
888 return SWITCH_STATUS_FALSE;
889 }
890
891 if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
892 return SWITCH_STATUS_SUCCESS;
893 }
894
895 switch (msg->message_id) {
896 case SWITCH_MESSAGE_INDICATE_PROGRESS:
897 case SWITCH_MESSAGE_INDICATE_ANSWER:
898 ftdm_channel_call_answer(tech_pvt->ftdmchan);
899 break;
900 default:
901 break;
902 }
903
904 return SWITCH_STATUS_SUCCESS;
905 }
906
907 static switch_status_t channel_receive_message_fxs(switch_core_session_t *session, switch_core_session_message_t *msg)
908 {
909 switch_channel_t *channel;
910 private_t *tech_pvt;
911
912 channel = switch_core_session_get_channel(session);
913 assert(channel != NULL);
914
915 tech_pvt = (private_t *) switch_core_session_get_private(session);
916 assert(tech_pvt != NULL);
917
918 if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
919 switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
920 return SWITCH_STATUS_FALSE;
921 }
922
923 if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
924 return SWITCH_STATUS_SUCCESS;
925 }
926
927 switch (msg->message_id) {
928 case SWITCH_MESSAGE_INDICATE_PROGRESS:
929 case SWITCH_MESSAGE_INDICATE_ANSWER:
930 ftdm_channel_call_answer(tech_pvt->ftdmchan);
931 switch_channel_mark_answered(channel);
932 break;
933 case SWITCH_MESSAGE_INDICATE_RINGING:
934 if (!switch_channel_test_flag(channel, CF_ANSWERED) &&
935 !switch_channel_test_flag(channel, CF_EARLY_MEDIA) &&
936 !switch_channel_test_flag(channel, CF_RING_READY)
937 ) {
938 ftdm_channel_call_indicate(tech_pvt->ftdmchan, FTDM_CHANNEL_INDICATE_RING);
939 switch_channel_mark_ring_ready(channel);
940 }
941 break;
942 default:
943 break;
944 }
945
946 return SWITCH_STATUS_SUCCESS;
947 }
948
949 static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
950 {
951 private_t *tech_pvt;
952 switch_status_t status;
953 switch_channel_t *channel;
954 const char *var;
955 ftdm_channel_t *ftdmchan = NULL;
956
957 tech_pvt = (private_t *) switch_core_session_get_private(session);
958 assert(tech_pvt != NULL);
959
960 channel = switch_core_session_get_channel(session);
961
962 if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
963 switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
964 return SWITCH_STATUS_FALSE;
965 }
966
967 if (!(ftdmchan = tech_pvt->ftdmchan)) {
968 switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
969 return SWITCH_STATUS_FALSE;
970 }
971
972 if (!tech_pvt->ftdmchan) {
973 switch_channel_hangup(channel, SWITCH_CAUSE_LOSE_RACE);
974 return SWITCH_STATUS_FALSE;
975 }
976
977 switch (msg->message_id) {
978 case SWITCH_MESSAGE_INDICATE_PROGRESS:
979 case SWITCH_MESSAGE_INDICATE_ANSWER:
980 if (!switch_channel_test_flag(channel, CF_OUTBOUND)) {
981 if ((var = switch_channel_get_variable(channel, "freetdm_pre_buffer_size"))) {
982 int tmp = atoi(var);
983 if (tmp > -1) {
984 ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tmp);
985 }
986 }
987 if ((var = switch_channel_get_variable(channel, "freetdm_disable_dtmf"))) {
988 ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL);
989 }
990 }
991 break;
992 case SWITCH_MESSAGE_INDICATE_UUID_CHANGE:
993 {
994 ftdm_channel_replace_token(tech_pvt->ftdmchan, msg->string_array_arg[0], msg->string_array_arg[1]);
995 }
996 break;
997 default:
998 break;
999 }
1000
1001 switch (ftdm_channel_get_type(tech_pvt->ftdmchan)) {
1002 case FTDM_CHAN_TYPE_FXS:
1003 case FTDM_CHAN_TYPE_EM:
1004 status = channel_receive_message_fxs(session, msg);
1005 break;
1006 case FTDM_CHAN_TYPE_FXO:
1007 status = channel_receive_message_fxo(session, msg);
1008 break;
1009 case FTDM_CHAN_TYPE_B:
1010 status = channel_receive_message_b(session, msg);
1011 break;
1012 case FTDM_CHAN_TYPE_CAS:
1013 status = channel_receive_message_cas(session, msg);
1014 break;
1015 default:
1016 status = SWITCH_STATUS_FALSE;
1017 break;
1018 }
1019
1020 return status;
1021
1022 }
1023
1024 switch_state_handler_table_t freetdm_state_handlers = {
1025 channel_on_init,
1026 channel_on_routing,
1027 channel_on_execute,
1028 channel_on_hangup,
1029 channel_on_exchange_media,
1030 channel_on_soft_execute,
1031 NULL,
1032 NULL,
1033 NULL,
1034 NULL,
1035 NULL,
1036 channel_on_destroy
1037
1038 };
1039
1040 switch_io_routines_t freetdm_io_routines = {
1041 channel_outgoing_channel,
1042 channel_read_frame,
1043 channel_write_frame,
1044 channel_kill_channel,
1045 channel_send_dtmf,
1046 channel_receive_message
1047 };
1048
1049
1050
1051
1052 static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
1053 switch_caller_profile_t *outbound_profile,
1054 switch_core_session_t **new_session, switch_memory_pool_t **pool,
1055 switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
1056 {
1057
1058 const char *dest = NULL;
1059 char *data = NULL;
1060 int span_id = -1, group_id = -1, chan_id = 0;
1061 ftdm_channel_t *ftdmchan = NULL;
1062 switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1063 char name[128];
1064 ftdm_status_t status;
1065 int direction = FTDM_TOP_DOWN;
1066 ftdm_caller_data_t caller_data = {{ 0 }};
1067 char *span_name = NULL;
1068 switch_event_header_t *h;
1069 char *argv[3];
1070 int argc = 0;
1071 const char *var;
1072 const char *dest_num = NULL, *callerid_num = NULL;
1073
1074 if (!outbound_profile) {
1075 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing caller profile\n");
1076 return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1077 }
1078
1079 if (zstr(outbound_profile->destination_number)) {
1080 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid dial string\n");
1081 return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1082 }
1083
1084
1085 data = switch_core_strdup(outbound_profile->pool, outbound_profile->destination_number);
1086
1087 if (!zstr(outbound_profile->destination_number)) {
1088 dest_num = switch_sanitize_number(switch_core_strdup(outbound_profile->pool, outbound_profile->destination_number));
1089 }
1090
1091 if (!zstr(outbound_profile->caller_id_number)) {
1092 callerid_num = switch_sanitize_number(switch_core_strdup(outbound_profile->pool, outbound_profile->caller_id_number));
1093 }
1094
1095 if (!zstr(callerid_num) && !strcmp(callerid_num, "0000000000")) {
1096 callerid_num = NULL;
1097 }
1098
1099 if ((argc = switch_separate_string(data, '/', argv, (sizeof(argv) / sizeof(argv[0])))) < 2) {
1100 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid dial string\n");
1101 return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1102 }
1103
1104 if (switch_is_number(argv[0])) {
1105 span_id = atoi(argv[0]);
1106 } else {
1107 span_name = argv[0];
1108 }
1109
1110 if (*argv[1] == 'A') {
1111 direction = FTDM_BOTTOM_UP;
1112 } else if (*argv[1] == 'a') {
1113 direction = FTDM_TOP_DOWN;
1114 } else {
1115 chan_id = atoi(argv[1]);
1116 }
1117
1118 if (!(dest = argv[2])) {
1119 dest = "";
1120 }
1121
1122 if (span_id == 0 && chan_id != 0) {
1123 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Span 0 is used to pick the first available span, selecting a channel is not supported (and doesn't make sense)\n");
1124 return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1125 }
1126
1127 if (span_id == -1 && !zstr(span_name)) {
1128 ftdm_span_t *span;
1129 ftdm_status_t zstatus = ftdm_span_find_by_name(span_name, &span);
1130 if (zstatus == FTDM_SUCCESS && span) {
1131 span_id = ftdm_span_get_id(span);
1132 }
1133 }
1134
1135 if (span_id == -1) {
1136
1137 ftdm_group_t *group;
1138 ftdm_status_t zstatus = ftdm_group_find_by_name(span_name, &group);
1139 if (zstatus == FTDM_SUCCESS && group) {
1140 group_id = ftdm_group_get_id(group);
1141 } else {
1142 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing ftdm span or group: %s\n", span_name);
1143 return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1144 }
1145 }
1146
1147 if (group_id < 0 && chan_id < 0) {
1148 direction = FTDM_BOTTOM_UP;
1149 chan_id = 0;
1150 }
1151
1152 if (session && globals.sip_headers) {
1153 switch_channel_t *channel = switch_core_session_get_channel(session);
1154 const char *sipvar;
1155 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CallerName");
1156 if (sipvar) {
1157 ftdm_set_string(caller_data.cid_name, sipvar);
1158 }
1159
1160 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CallerNumber");
1161 if (sipvar) {
1162 ftdm_set_string(caller_data.cid_num.digits, sipvar);
1163 }
1164
1165 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI");
1166 if (sipvar) {
1167 ftdm_set_string(caller_data.ani.digits, sipvar);
1168 }
1169
1170 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI-TON");
1171 if (sipvar) {
1172 caller_data.ani.type = (uint8_t)atoi(sipvar);
1173 }
1174
1175 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI-Plan");
1176 if (sipvar) {
1177 caller_data.ani.plan = (uint8_t)atoi(sipvar);
1178 }
1179
1180 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-ANI2");
1181 if (sipvar) {
1182 ftdm_set_string(caller_data.aniII, sipvar);
1183 }
1184
1185 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS");
1186 if (sipvar) {
1187 ftdm_set_string(caller_data.dnis.digits, sipvar);
1188 }
1189
1190 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS-TON");
1191 if (sipvar) {
1192 caller_data.dnis.type = (uint8_t)atoi(sipvar);
1193 }
1194
1195 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-DNIS-Plan");
1196 if (sipvar) {
1197 caller_data.dnis.plan = (uint8_t)atoi(sipvar);
1198 }
1199
1200 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS");
1201 if (sipvar) {
1202 ftdm_set_string(caller_data.rdnis.digits, sipvar);
1203 }
1204
1205 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-TON");
1206 if (sipvar) {
1207 caller_data.rdnis.type = (uint8_t)atoi(sipvar);
1208 }
1209
1210 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-RDNIS-Plan");
1211 if (sipvar) {
1212 caller_data.rdnis.plan = (uint8_t)atoi(sipvar);
1213 }
1214
1215 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-Screen");
1216 if (sipvar) {
1217 caller_data.screen = (uint8_t)atoi(sipvar);
1218 }
1219
1220 sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-Presentation");
1221 if (sipvar) {
1222 caller_data.pres = (uint8_t)atoi(sipvar);
1223 }
1224 }
1225
1226 if (session) {
1227
1228 switch_channel_t *channel = switch_core_session_get_channel(session);
1229 const char *freetdmvar;
1230 freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_capability");
1231 if (freetdmvar) {
1232 caller_data.bearer_capability = (uint8_t)atoi(freetdmvar);
1233 }
1234 freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_layer1");
1235 if (freetdmvar) {
1236 caller_data.bearer_layer1 = (uint8_t)atoi(freetdmvar);
1237 }
1238 }
1239
1240 if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) {
1241 caller_data.screen = 1;
1242 }
1243
1244 if (switch_test_flag(outbound_profile, SWITCH_CPF_HIDE_NUMBER)) {
1245 caller_data.pres = 1;
1246 }
1247
1248 if (!zstr(dest)) {
1249 ftdm_set_string(caller_data.dnis.digits, dest);
1250 }
1251
1252 if ((var = switch_event_get_header(var_event, "freetdm_outbound_ton")) || (var = switch_core_get_variable("freetdm_outbound_ton"))) {
1253 if (!strcasecmp(var, "national")) {
1254 caller_data.dnis.type = FTDM_TON_NATIONAL;
1255 } else if (!strcasecmp(var, "international")) {
1256 caller_data.dnis.type = FTDM_TON_INTERNATIONAL;
1257 } else if (!strcasecmp(var, "local")) {
1258 caller_data.dnis.type = FTDM_TON_SUBSCRIBER_NUMBER;
1259 } else if (!strcasecmp(var, "unknown")) {
1260 caller_data.dnis.type = FTDM_TON_UNKNOWN;
1261 }
1262 } else {
1263 caller_data.dnis.type = outbound_profile->destination_number_ton;
1264 }
1265
1266 if ((var = switch_event_get_header(var_event, "freetdm_custom_call_data")) || (var = switch_core_get_variable("freetdm_custom_call_data"))) {
1267 ftdm_set_string(caller_data.raw_data, var);
1268 caller_data.raw_data_len = (uint32_t)strlen(var);
1269 }
1270
1271 caller_data.dnis.plan = outbound_profile->destination_number_numplan;
1272
1273
1274
1275 caller_data.cid_num.type = outbound_profile->caller_ton;
1276 caller_data.cid_num.plan = outbound_profile->caller_numplan;
1277 caller_data.rdnis.type = outbound_profile->rdnis_ton;
1278 caller_data.rdnis.plan = outbound_profile->rdnis_numplan;
1279
1280 ftdm_set_string(caller_data.cid_name, outbound_profile->caller_id_name);
1281 ftdm_set_string(caller_data.cid_num.digits, switch_str_nil(outbound_profile->caller_id_number));
1282
1283 if (group_id >= 0) {
1284 status = ftdm_channel_open_by_group(group_id, direction, &caller_data, &ftdmchan);
1285 } else if (chan_id) {
1286 status = ftdm_channel_open(span_id, chan_id, &ftdmchan);
1287 } else {
1288 status = ftdm_channel_open_by_span(span_id, direction, &caller_data, &ftdmchan);
1289 }
1290
1291 if (status != FTDM_SUCCESS) {
1292 if (caller_data.hangup_cause == SWITCH_CAUSE_NONE) {
1293 caller_data.hangup_cause = SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION;
1294 }
1295 return caller_data.hangup_cause;
1296 }
1297
1298 if ((var = switch_event_get_header(var_event, "freetdm_pre_buffer_size"))) {
1299 int tmp = atoi(var);
1300 if (tmp > -1) {
1301 ftdm_channel_command(ftdmchan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tmp);
1302 }
1303 }
1304
1305 span_id = ftdm_channel_get_span_id(ftdmchan);
1306 chan_id = ftdm_channel_get_id(ftdmchan);
1307
1308 for (h = var_event->headers; h; h = h->next) {
1309 if (!strncasecmp(h->name, FREETDM_VAR_PREFIX, FREETDM_VAR_PREFIX_LEN)) {
1310 char *v = h->name + FREETDM_VAR_PREFIX_LEN;
1311 if (!zstr(v)) {
1312 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s=%s to channel %d:%d\n", v, h->value, span_id, chan_id);
1313 ftdm_channel_add_var(ftdmchan, v, h->value);
1314 }
1315 }
1316 }
1317
1318 if ((*new_session = switch_core_session_request(freetdm_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool)) != 0) {
1319 private_t *tech_pvt;
1320 switch_caller_profile_t *caller_profile;
1321 switch_channel_t *channel = switch_core_session_get_channel(*new_session);
1322
1323 switch_core_session_add_stream(*new_session, NULL);
1324 if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) {
1325 tech_init(tech_pvt, *new_session, ftdmchan);
1326 } else {
1327 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
1328 switch_core_session_destroy(new_session);
1329 cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1330 goto fail;
1331 }
1332
1333 snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", span_id, chan_id, dest);
1334 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name);
1335 switch_channel_set_name(channel, name);
1336 switch_channel_set_variable(channel, "freetdm_span_name", ftdm_channel_get_span_name(ftdmchan));
1337 switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", span_id);
1338 switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chan_id);
1339 ftdm_channel_set_caller_data(ftdmchan, &caller_data);
1340 caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
1341 caller_profile->destination_number = switch_core_strdup(caller_profile->pool, switch_str_nil(dest_num));
1342 caller_profile->caller_id_number = switch_core_strdup(caller_profile->pool, switch_str_nil(callerid_num));
1343 switch_channel_set_caller_profile(channel, caller_profile);
1344 tech_pvt->caller_profile = caller_profile;
1345
1346
1347 switch_channel_set_flag(channel, CF_OUTBOUND);
1348 switch_channel_set_state(channel, CS_INIT);
1349 if (ftdm_channel_add_token(ftdmchan, switch_core_session_get_uuid(*new_session), ftdm_channel_get_token_count(ftdmchan)) != FTDM_SUCCESS) {
1350 switch_core_session_destroy(new_session);
1351 cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1352 goto fail;
1353 }
1354
1355
1356 if (SPAN_CONFIG[span_id].limit_calls) {
1357 char spanresource[512];
1358 snprintf(spanresource, sizeof(spanresource), "span_%s_%s", ftdm_channel_get_span_name(ftdmchan), caller_data.dnis.digits);
1359 ftdm_log(FTDM_LOG_DEBUG, "Adding rate limit resource on channel %d:%d (%s/%s/%d/%d)\n", span_id, chan_id, FREETDM_LIMIT_REALM,
1360 spanresource, SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds);
1361 if (switch_limit_incr("hash", *new_session, FREETDM_LIMIT_REALM, spanresource, SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds) != SWITCH_STATUS_SUCCESS) {
1362 switch_core_session_destroy(new_session);
1363 cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1364 goto fail;
1365 }
1366 }
1367
1368 if ((status = ftdm_channel_call_place(ftdmchan)) != FTDM_SUCCESS) {
1369 if (tech_pvt->read_codec.implementation) {
1370 switch_core_codec_destroy(&tech_pvt->read_codec);
1371 }
1372
1373 if (tech_pvt->write_codec.implementation) {
1374 switch_core_codec_destroy(&tech_pvt->write_codec);
1375 }
1376 switch_core_session_destroy(new_session);
1377 if (status == FTDM_BREAK) {
1378 cause = SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION;
1379 ftdmchan = NULL;
1380 } else {
1381 cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
1382 }
1383 goto fail;
1384 }
1385
1386 ftdm_channel_init(ftdmchan);
1387
1388 return SWITCH_CAUSE_SUCCESS;
1389 }
1390
1391 fail:
1392
1393 if (ftdmchan) {
1394 ftdm_channel_call_hangup_with_cause(ftdmchan, FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE);
1395 }
1396
1397 return cause;
1398
1399 }
1400
1401 ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session_t **sp)
1402 {
1403 switch_core_session_t *session = NULL;
1404 private_t *tech_pvt = NULL;
1405 switch_channel_t *channel = NULL;
1406 ftdm_iterator_t *iter = NULL;
1407 ftdm_iterator_t *curr = NULL;
1408 const char *var_name = NULL;
1409 const char *var_value = NULL;
1410 uint32_t spanid, chanid;
1411 char name[128];
1412 ftdm_caller_data_t *channel_caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
1413
1414 *sp = NULL;
1415
1416 spanid = ftdm_channel_get_span_id(sigmsg->channel);
1417 chanid = ftdm_channel_get_id(sigmsg->channel);
1418
1419 if (!(session = switch_core_session_request(freetdm_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL))) {
1420 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n");
1421 return FTDM_FAIL;
1422 }
1423
1424 switch_core_session_add_stream(session, NULL);
1425
1426 tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t));
1427 assert(tech_pvt != NULL);
1428 channel = switch_core_session_get_channel(session);
1429 if (tech_init(tech_pvt, session, sigmsg->channel) != SWITCH_STATUS_SUCCESS) {
1430 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n");
1431 switch_core_session_destroy(&session);
1432 return FTDM_FAIL;
1433 }
1434
1435 channel_caller_data->collected[0] = '\0';
1436
1437 if (zstr(channel_caller_data->cid_name)) {
1438 switch_set_string(channel_caller_data->cid_name, ftdm_channel_get_name(sigmsg->channel));
1439 }
1440
1441 if (zstr(channel_caller_data->cid_num.digits)) {
1442 if (!zstr(channel_caller_data->ani.digits)) {
1443 switch_set_string(channel_caller_data->cid_num.digits, channel_caller_data->ani.digits);
1444 } else {
1445 switch_set_string(channel_caller_data->cid_num.digits, ftdm_channel_get_number(sigmsg->channel));
1446 }
1447 }
1448
1449 tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
1450 "FreeTDM",
1451 SPAN_CONFIG[spanid].dialplan,
1452 channel_caller_data->cid_name,
1453 channel_caller_data->cid_num.digits,
1454 NULL,
1455 channel_caller_data->ani.digits,
1456 channel_caller_data->aniII,
1457 channel_caller_data->rdnis.digits,
1458 (char *)modname,
1459 SPAN_CONFIG[spanid].context,
1460 channel_caller_data->dnis.digits);
1461
1462 assert(tech_pvt->caller_profile != NULL);
1463
1464 if (channel_caller_data->screen == 1 || channel_caller_data->screen == 3) {
1465 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_SCREEN);
1466 }
1467
1468 tech_pvt->caller_profile->caller_ton = channel_caller_data->cid_num.type;
1469 tech_pvt->caller_profile->caller_numplan = channel_caller_data->cid_num.plan;
1470 tech_pvt->caller_profile->ani_ton = channel_caller_data->ani.type;
1471 tech_pvt->caller_profile->ani_numplan = channel_caller_data->ani.plan;
1472 tech_pvt->caller_profile->destination_number_ton = channel_caller_data->dnis.type;
1473 tech_pvt->caller_profile->destination_number_numplan = channel_caller_data->dnis.plan;
1474 tech_pvt->caller_profile->rdnis_ton = channel_caller_data->rdnis.type;
1475 tech_pvt->caller_profile->rdnis_numplan = channel_caller_data->rdnis.plan;
1476
1477 if (channel_caller_data->pres) {
1478 switch_set_flag(tech_pvt->caller_profile, SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER);
1479 }
1480
1481 snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", spanid, chanid, tech_pvt->caller_profile->destination_number);
1482 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect inbound channel %s\n", name);
1483 switch_channel_set_name(channel, name);
1484 switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
1485
1486 switch_channel_set_variable(channel, "freetdm_span_name", ftdm_channel_get_span_name(sigmsg->channel));
1487 switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", spanid);
1488 switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chanid);
1489 switch_channel_set_variable_printf(channel, "freetdm_bearer_capability", "%d", channel_caller_data->bearer_capability);
1490 switch_channel_set_variable_printf(channel, "freetdm_bearer_layer1", "%d", channel_caller_data->bearer_layer1);
1491 if (globals.sip_headers) {
1492 switch_channel_set_variable(channel, "sip_h_X-FreeTDM-SpanName", ftdm_channel_get_span_name(sigmsg->channel));
1493 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-SpanNumber", "%d", spanid);
1494 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ChanNumber", "%d", chanid);
1495
1496 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CallerName", "%s", channel_caller_data->cid_name);
1497 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CallerNumber", "%s", channel_caller_data->cid_num.digits);
1498
1499 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI", "%s", channel_caller_data->ani.digits);
1500 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI-TON", "%d", channel_caller_data->ani.type);
1501 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI-Plan", "%d", channel_caller_data->ani.plan);
1502 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-ANI2", "%s", channel_caller_data->aniII);
1503
1504 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS", "%s", channel_caller_data->dnis.digits);
1505 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-TON", "%s", channel_caller_data->dnis.type);
1506 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-DNIS-Plan", "%s", channel_caller_data->dnis.plan);
1507
1508 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS", "%s", channel_caller_data->rdnis.digits);
1509 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-TON", "%d", channel_caller_data->rdnis.type);
1510 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Plan", "%d", channel_caller_data->rdnis.plan);
1511
1512 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Screen", "%d", channel_caller_data->screen);
1513 switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Presentation", "%d", channel_caller_data->pres);
1514 }
1515 if (channel_caller_data->raw_data_len) {
1516 switch_channel_set_variable_printf(channel, "freetdm_custom_call_data", "%s", channel_caller_data->raw_data);
1517 }
1518
1519 iter = ftdm_channel_get_var_iterator(sigmsg->channel, NULL);
1520 for (curr = iter ; curr; curr = ftdm_iterator_next(curr)) {
1521 ftdm_channel_get_current_var(curr, &var_name, &var_value);
1522 snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name);
1523 switch_channel_set_variable_printf(channel, name, "%s", var_value);
1524 }
1525 ftdm_iterator_free(iter);
1526
1527 switch_channel_set_state(channel, CS_INIT);
1528 if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
1529 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
1530 switch_core_session_destroy(&session);
1531 return FTDM_FAIL;
1532 }
1533
1534 if (ftdm_channel_add_token(sigmsg->channel, switch_core_session_get_uuid(session), 0) != FTDM_SUCCESS) {
1535 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error adding token\n");
1536 switch_core_session_destroy(&session);
1537 return FTDM_FAIL;
1538 }
1539 *sp = session;
1540
1541 return FTDM_SUCCESS;
1542 }
1543
1544 static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
1545 {
1546 switch_event_t *event = NULL;
1547 ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE;
1548 uint32_t chanid, spanid;
1549 chanid = ftdm_channel_get_id(sigmsg->channel);
1550 spanid = ftdm_channel_get_span_id(sigmsg->channel);
1551 switch (sigmsg->event_id) {
1552
1553 case FTDM_SIGEVENT_ALARM_CLEAR:
1554 case FTDM_SIGEVENT_ALARM_TRAP:
1555 {
1556 if (ftdm_channel_get_alarms(sigmsg->channel, &alarmbits) != FTDM_SUCCESS) {
1557 ftdm_log(FTDM_LOG_ERROR, "failed to retrieve alarms\n");
1558 return FTDM_FAIL;
1559 }
1560 if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
1561 ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n");
1562 return FTDM_FAIL;
1563 }
1564 if (sigmsg->event_id == FTDM_SIGEVENT_ALARM_CLEAR) {
1565 ftdm_log(FTDM_LOG_NOTICE, "Alarm cleared on channel %d:%d\n", spanid, chanid);
1566 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear");
1567 } else {
1568 ftdm_log(FTDM_LOG_NOTICE, "Alarm raised on channel %d:%d\n", spanid, chanid);
1569 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap");
1570 }
1571 }
1572 break;
1573 case FTDM_SIGEVENT_UP:
1574 {
1575
1576 char spanresource[512];
1577 if (SPAN_CONFIG[spanid].limit_reset_event == FTDM_LIMIT_RESET_ON_ANSWER && SPAN_CONFIG[spanid].limit_calls) {
1578 ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
1579 snprintf(spanresource, sizeof(spanresource), "span_%s_%s", ftdm_channel_get_span_name(sigmsg->channel), caller_data->dnis.digits);
1580 ftdm_log(FTDM_LOG_DEBUG, "Clearing rate limit resource on channel %d:%d (%s/%s)\n", spanid, chanid, FREETDM_LIMIT_REALM, spanresource);
1581 switch_limit_interval_reset("hash", FREETDM_LIMIT_REALM, spanresource);
1582 }
1583 return FTDM_SUCCESS;
1584 }
1585 default:
1586 return FTDM_SUCCESS;
1587 break;
1588 }
1589
1590 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(sigmsg->channel));
1591 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(sigmsg->channel));
1592 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(sigmsg->channel));
1593
1594 if (alarmbits & FTDM_ALARM_RED) {
1595 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red");
1596 }
1597 if (alarmbits & FTDM_ALARM_YELLOW) {
1598 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow");
1599 }
1600 if (alarmbits & FTDM_ALARM_RAI) {
1601 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai");
1602 }
1603 if (alarmbits & FTDM_ALARM_BLUE) {
1604 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue");
1605 }
1606 if (alarmbits & FTDM_ALARM_AIS) {
1607 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais");
1608 }
1609 if (alarmbits & FTDM_ALARM_GENERAL) {
1610 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general");
1611 }
1612 switch_event_fire(&event);
1613
1614 return FTDM_BREAK;
1615 }
1616
1617 static void ftdm_enable_channel_dtmf(ftdm_channel_t *fchan, switch_channel_t *channel)
1618 {
1619 if (channel) {
1620 const char *var;
1621 if ((var = switch_channel_get_variable(channel, "freetdm_disable_dtmf"))) {
1622 if (switch_true(var)) {
1623 ftdm_channel_command(fchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL);
1624 ftdm_log(FTDM_LOG_INFO, "DTMF detection disabled in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan));
1625 return;
1626 }
1627 }
1628
1629 }
1630 if (ftdm_channel_command(fchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, NULL) != FTDM_SUCCESS) {
1631 ftdm_log(FTDM_LOG_ERROR, "Failed to enable DTMF detection in channel %d:%d\n", ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan));
1632 }
1633 }
1634
1635 static FIO_SIGNAL_CB_FUNCTION(on_fxo_signal)
1636 {
1637 switch_core_session_t *session = NULL;
1638 switch_channel_t *channel = NULL;
1639 ftdm_status_t status;
1640 uint32_t spanid;
1641 uint32_t chanid;
1642 ftdm_caller_data_t *callerdata;
1643
1644 spanid = ftdm_channel_get_span_id(sigmsg->channel);
1645 chanid = ftdm_channel_get_id(sigmsg->channel);
1646 callerdata = ftdm_channel_get_caller_data(sigmsg->channel);
1647
1648 ftdm_log(FTDM_LOG_DEBUG, "got FXO sig %d:%d [%s]\n", spanid, chanid, ftdm_signal_event2str(sigmsg->event_id));
1649
1650 switch(sigmsg->event_id) {
1651
1652 case FTDM_SIGEVENT_PROGRESS_MEDIA:
1653 {
1654 if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
1655 channel = switch_core_session_get_channel(session);
1656 switch_channel_mark_pre_answered(channel);
1657 switch_core_session_rwunlock(session);
1658 }
1659 }
1660 break;
1661 case FTDM_SIGEVENT_STOP:
1662 {
1663 private_t *tech_pvt = NULL;
1664 while((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
1665 tech_pvt = switch_core_session_get_private(session);
1666 switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
1667 ftdm_channel_clear_token(sigmsg->channel, 0);
1668 channel = switch_core_session_get_channel(session);
1669 switch_channel_hangup(channel, callerdata->hangup_cause);
1670 ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session));
1671 switch_core_session_rwunlock(session);
1672 }
1673 }
1674 break;
1675 case FTDM_SIGEVENT_UP:
1676 {
1677 if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
1678 channel = switch_core_session_get_channel(session);
1679 switch_channel_mark_answered(channel);
1680 ftdm_enable_channel_dtmf(sigmsg->channel, channel);
1681 switch_core_session_rwunlock(session);
1682 }
1683 }
1684 break;
1685 case FTDM_SIGEVENT_START:
1686 {
1687 status = ftdm_channel_from_event(sigmsg, &session);
1688 if (status != FTDM_SUCCESS) {
1689 ftdm_channel_call_hangup(sigmsg->channel);
1690 }
1691 }
1692 break;
1693
1694 default:
1695 {
1696 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n",
1697 sigmsg->event_id, spanid, chanid);
1698 }
1699 break;
1700
1701 }
1702
1703 return FTDM_SUCCESS;
1704 }
1705
1706 static FIO_SIGNAL_CB_FUNCTION(on_fxs_signal)
1707 {
1708 switch_core_session_t *session = NULL;
1709 switch_channel_t *channel = NULL;
1710 ftdm_status_t status = FTDM_SUCCESS;
1711 uint32_t chanid, spanid, tokencount;
1712
1713 chanid = ftdm_channel_get_id(sigmsg->channel);
1714 spanid = ftdm_channel_get_span_id(sigmsg->channel);
1715 tokencount = ftdm_channel_get_token_count(sigmsg->channel);
1716
1717 ftdm_log(FTDM_LOG_DEBUG, "got FXS sig [%s]\n", ftdm_signal_event2str(sigmsg->event_id));
1718
1719 switch(sigmsg->event_id) {
1720 case FTDM_SIGEVENT_UP:
1721 {
1722 if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
1723 channel = switch_core_session_get_channel(session);
1724 switch_channel_mark_answered(channel);
1725 ftdm_enable_channel_dtmf(sigmsg->channel, channel);
1726 switch_core_session_rwunlock(session);
1727 }
1728 }
1729 break;
1730 case FTDM_SIGEVENT_PROGRESS:
1731 {
1732 if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
1733 channel = switch_core_session_get_channel(session);
1734 switch_channel_mark_ring_ready(channel);
1735 switch_core_session_rwunlock(session);
1736 }
1737 }
1738 break;
1739 case FTDM_SIGEVENT_START:
1740 {
1741 status = ftdm_channel_from_event(sigmsg, &session);
1742 if (status != FTDM_SUCCESS) {
1743 ftdm_channel_call_indicate(sigmsg->channel, FTDM_CHANNEL_INDICATE_BUSY);
1744 }
1745 }
1746 break;
1747 case FTDM_SIGEVENT_STOP:
1748 {
1749 private_t *tech_pvt = NULL;
1750 switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
1751 if (tokencount) {
1752 ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
1753 switch_core_session_t *session_a, *session_b, *session_t = NULL;
1754 switch_channel_t *channel_a = NULL, *channel_b = NULL;
1755 int digits = !zstr(caller_data->collected);
1756 const char *br_a_uuid = NULL, *br_b_uuid = NULL;
1757 private_t *tech_pvt = NULL;
1758
1759
1760 if ((session_a = switch_core_session_locate(ftdm_channel_get_token(sigmsg->channel, 0)))) {
1761 channel_a = switch_core_session_get_channel(session_a);
1762 br_a_uuid = switch_channel_get_variable(channel_a, SWITCH_SIGNAL_BOND_VARIABLE);
1763
1764 tech_pvt = switch_core_session_get_private(session_a);
1765 stop_hold(session_a, switch_channel_get_variable(channel_a, SWITCH_SIGNAL_BOND_VARIABLE));
1766 switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
1767 }
1768
1769 if ((session_b = switch_core_session_locate(ftdm_channel_get_token(sigmsg->channel, 1)))) {
1770 channel_b = switch_core_session_get_channel(session_b);
1771 br_b_uuid = switch_channel_get_variable(channel_b, SWITCH_SIGNAL_BOND_VARIABLE);
1772
1773 tech_pvt = switch_core_session_get_private(session_b);
1774 stop_hold(session_a, switch_channel_get_variable(channel_b, SWITCH_SIGNAL_BOND_VARIABLE));
1775 switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
1776 }
1777
1778 if (channel_a && channel_b && !switch_channel_test_flag(channel_a, CF_OUTBOUND) && !switch_channel_test_flag(channel_b, CF_OUTBOUND)) {
1779 cause = SWITCH_CAUSE_ATTENDED_TRANSFER;
1780 if (br_a_uuid && br_b_uuid) {
1781 switch_ivr_uuid_bridge(br_a_uuid, br_b_uuid);
1782 } else if (br_a_uuid && digits) {
1783 session_t = switch_core_session_locate(br_a_uuid);
1784 } else if (br_b_uuid && digits) {
1785 session_t = switch_core_session_locate(br_b_uuid);
1786 }
1787 }
1788
1789 if (session_t) {
1790 switch_ivr_session_transfer(session_t, caller_data->collected, NULL, NULL);
1791 switch_core_session_rwunlock(session_t);
1792 }
1793
1794 if (session_a) {
1795 switch_core_session_rwunlock(session_a);
1796 }
1797
1798 if (session_b) {
1799 switch_core_session_rwunlock(session_b);
1800 }
1801
1802
1803 }
1804
1805 while((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
1806 tech_pvt = switch_core_session_get_private(session);
1807 switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
1808 channel = switch_core_session_get_channel(session);
1809 switch_channel_hangup(channel, cause);
1810 ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session));
1811 switch_core_session_rwunlock(session);
1812 }
1813 ftdm_channel_clear_token(sigmsg->channel, NULL);
1814
1815 }
1816 break;
1817
1818 case FTDM_SIGEVENT_ADD_CALL:
1819 {
1820 cycle_foreground(sigmsg->channel, 1, NULL);
1821 }
1822 break;
1823 case FTDM_SIGEVENT_FLASH:
1824 {
1825 chan_pvt_t *chanpvt = ftdm_channel_get_private(sigmsg->channel);
1826 if (!chanpvt) {
1827 ftdm_log(FTDM_LOG_ERROR, "%d:%d has no private data, can't handle FXS features! (this is a bug)\n",
1828 chanid, spanid);
1829 break;
1830 }
1831 if (ftdm_channel_call_check_hold(sigmsg->channel) && tokencount == 1) {
1832 switch_core_session_t *session;
1833 if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
1834 const char *buuid;
1835 switch_channel_t *channel;
1836 private_t *tech_pvt;
1837
1838 tech_pvt = switch_core_session_get_private(session);
1839 channel = switch_core_session_get_channel(session);
1840 buuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE);
1841 ftdm_channel_call_unhold(sigmsg->channel);
1842 stop_hold(session, buuid);
1843 switch_clear_flag_locked(tech_pvt, TFLAG_HOLD);
1844 switch_core_session_rwunlock(session);
1845 }
1846 } else if (tokencount == 2 && (SPAN_CONFIG[sigmsg->span_id].analog_options & ANALOG_OPTION_3WAY)) {
1847 if (switch_test_flag(chanpvt, ANALOG_OPTION_3WAY)) {
1848 switch_clear_flag(chanpvt, ANALOG_OPTION_3WAY);
1849 if ((session = ftdm_channel_get_session(sigmsg->channel, 1))) {
1850 channel = switch_core_session_get_channel(session);
1851 switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
1852 ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session));
1853 switch_core_session_rwunlock(session);
1854 }
1855 cycle_foreground(sigmsg->channel, 1, NULL);
1856 } else {
1857 char *cmd;
1858 cmd = switch_mprintf("three_way::%s", ftdm_channel_get_token(sigmsg->channel, 0));
1859 switch_set_flag(chanpvt, ANALOG_OPTION_3WAY);
1860 cycle_foreground(sigmsg->channel, 1, cmd);
1861 free(cmd);
1862 }
1863 } else if ((SPAN_CONFIG[sigmsg->span_id].analog_options & ANALOG_OPTION_CALL_SWAP)
1864 || (SPAN_CONFIG[sigmsg->span_id].analog_options & ANALOG_OPTION_3WAY)
1865 ) {
1866 cycle_foreground(sigmsg->channel, 1, NULL);
1867 if (tokencount == 1) {
1868 ftdm_channel_call_hold(sigmsg->channel);
1869 }
1870 }
1871
1872 }
1873 break;
1874
1875 case FTDM_SIGEVENT_COLLECTED_DIGIT:
1876 {
1877 int span_id = ftdm_channel_get_span_id(sigmsg->channel);
1878 char *dtmf = sigmsg->raw_data;
1879 char *regex = SPAN_CONFIG[span_id].dial_regex;
1880 char *fail_regex = SPAN_CONFIG[span_id].fail_dial_regex;
1881 ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
1882
1883 if (zstr(regex)) {
1884 regex = NULL;
1885 }
1886
1887 if (zstr(fail_regex)) {
1888 fail_regex = NULL;
1889 }
1890
1891 ftdm_log(FTDM_LOG_DEBUG, "got DTMF sig [%s]\n", dtmf);
1892 switch_set_string(caller_data->collected, dtmf);
1893
1894 if ((regex || fail_regex) && !zstr(dtmf)) {
1895 switch_regex_t *re = NULL;
1896 int ovector[30];
1897 int match = 0;
1898
1899 if (fail_regex) {
1900 match = switch_regex_perform(dtmf, fail_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
1901 status = match ? FTDM_SUCCESS : FTDM_BREAK;
1902 switch_regex_safe_free(re);
1903 ftdm_log(FTDM_LOG_DEBUG, "DTMF [%s] vs fail regex %s %s\n", dtmf, fail_regex, match ? "matched" : "did not match");
1904 }
1905
1906 if (status == FTDM_SUCCESS && regex) {
1907 match = switch_regex_perform(dtmf, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
1908 status = match ? FTDM_BREAK : FTDM_SUCCESS;
1909 switch_regex_safe_free(re);
1910 ftdm_log(FTDM_LOG_DEBUG, "DTMF [%s] vs dial regex %s %s\n", dtmf, regex, match ? "matched" : "did not match");
1911 }
1912 ftdm_log(FTDM_LOG_DEBUG, "returning %s to COLLECT event with DTMF %s\n", status == FTDM_SUCCESS ? "success" : "break", dtmf);
1913 }
1914 }
1915 break;
1916
1917 default:
1918 {
1919 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n",
1920 sigmsg->event_id, spanid, chanid);
1921 }
1922 break;
1923
1924 }
1925
1926 return status;
1927 }
1928
1929 static FIO_SIGNAL_CB_FUNCTION(on_r2_signal)
1930 {
1931 uint32_t phyid, chanid, spanid;
1932 switch_core_session_t *session = NULL;
1933 switch_channel_t *channel = NULL;
1934 ftdm_status_t status = FTDM_SUCCESS;
1935 ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
1936
1937 phyid = ftdm_channel_get_ph_id(sigmsg->channel);
1938 chanid = ftdm_channel_get_id(sigmsg->channel);
1939 spanid = ftdm_channel_get_span_id(sigmsg->channel);
1940
1941 ftdm_log(FTDM_LOG_DEBUG, "Got R2 channel sig [%s] in channel %d\n", ftdm_signal_event2str(sigmsg->event_id), phyid);
1942
1943 if (on_common_signal(sigmsg) == FTDM_BREAK) {
1944 return FTDM_SUCCESS;
1945 }
1946
1947 switch(sigmsg->event_id) {
1948
1949 case FTDM_SIGEVENT_STOP:
1950 {
1951 private_t *tech_pvt = NULL;
1952 while((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
1953 tech_pvt = switch_core_session_get_private(session);
1954 switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
1955 channel = switch_core_session_get_channel(session);
1956 switch_channel_hangup(channel, caller_data->hangup_cause);
1957 ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session));
1958 switch_core_session_rwunlock(session);
1959 }
1960 }
1961 break;
1962
1963
1964 case FTDM_SIGEVENT_START:
1965 {
1966 status = ftdm_channel_from_event(sigmsg, &session);
1967 }
1968 break;
1969
1970
1971 case FTDM_SIGEVENT_COLLECTED_DIGIT:
1972 {
1973 ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
1974 int span_id = ftdm_channel_get_span_id(sigmsg->channel);
1975 char *regex = SPAN_CONFIG[span_id].dial_regex;
1976 char *fail_regex = SPAN_CONFIG[span_id].fail_dial_regex;
1977
1978 if (zstr(regex)) {
1979 regex = NULL;
1980 }
1981
1982 if (zstr(fail_regex)) {
1983 fail_regex = NULL;
1984 }
1985
1986 ftdm_log(FTDM_LOG_DEBUG, "R2 DNIS so far [%s]\n", caller_data->dnis.digits);
1987
1988 if ((regex || fail_regex) && !zstr(caller_data->dnis.digits)) {
1989 switch_regex_t *re = NULL;
1990 int ovector[30];
1991 int match = 0;
1992
1993 if (fail_regex) {
1994 match = switch_regex_perform(caller_data->dnis.digits, fail_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
1995 status = match ? FTDM_SUCCESS : FTDM_BREAK;
1996 switch_regex_safe_free(re);
1997 }
1998
1999 if (status == FTDM_SUCCESS && regex) {
2000 match = switch_regex_perform(caller_data->dnis.digits, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
2001 status = match ? FTDM_BREAK : FTDM_SUCCESS;
2002 }
2003
2004 switch_regex_safe_free(re);
2005 }
2006 }
2007 break;
2008
2009 case FTDM_SIGEVENT_PROGRESS:
2010 {
2011 if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
2012 channel = switch_core_session_get_channel(session);
2013 switch_channel_mark_ring_ready(channel);
2014 switch_core_session_rwunlock(session);
2015 }
2016 }
2017 break;
2018
2019 case FTDM_SIGEVENT_UP:
2020 {
2021 if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
2022 channel = switch_core_session_get_channel(session);
2023 switch_channel_mark_answered(channel);
2024 ftdm_enable_channel_dtmf(sigmsg->channel, channel);
2025 switch_core_session_rwunlock(session);
2026 }
2027 }
2028 break;
2029
2030 default:
2031 {
2032 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled event %d from R2 for channel %d:%d\n",
2033 sigmsg->event_id, spanid, chanid);
2034 }
2035 break;
2036 }
2037
2038 return status;
2039 }
2040
2041 static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
2042 {
2043 switch_core_session_t *session = NULL;
2044 switch_channel_t *channel = NULL;
2045 ftdm_caller_data_t *caller_data;
2046 uint32_t spanid, chanid;
2047
2048 ftdm_log(FTDM_LOG_DEBUG, "got clear channel sig [%s]\n", ftdm_signal_event2str(sigmsg->event_id));
2049
2050 caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
2051 chanid = ftdm_channel_get_id(sigmsg->channel);
2052 spanid = ftdm_channel_get_span_id(sigmsg->channel);
2053
2054 if (on_common_signal(sigmsg) == FTDM_BREAK) {
2055 return FTDM_SUCCESS;
2056 }
2057
2058 switch(sigmsg->event_id) {
2059 case FTDM_SIGEVENT_START:
2060 {
2061 ftdm_enable_channel_dtmf(sigmsg->channel, NULL);
2062 return ftdm_channel_from_event(sigmsg, &session);
2063 }
2064 break;
2065 case FTDM_SIGEVENT_STOP:
2066 case FTDM_SIGEVENT_RESTART:
2067 {
2068 private_t *tech_pvt = NULL;
2069 while((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
2070 tech_pvt = switch_core_session_get_private(session);
2071 switch_set_flag_locked(tech_pvt, TFLAG_DEAD);
2072 channel = switch_core_session_get_channel(session);
2073 switch_channel_hangup(channel, caller_data->hangup_cause);
2074 ftdm_channel_clear_token(sigmsg->channel, switch_core_session_get_uuid(session));
2075 switch_core_session_rwunlock(session);
2076 }
2077 }
2078 break;
2079 case FTDM_SIGEVENT_UP:
2080 {
2081 if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
2082 channel = switch_core_session_get_channel(session);
2083 switch_channel_mark_answered(channel);
2084 ftdm_enable_channel_dtmf(sigmsg->channel, channel);
2085 switch_core_session_rwunlock(session);
2086 } else {
2087 const char *uuid = ftdm_channel_get_uuid(sigmsg->channel, 0);
2088
2089 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session for channel %d:%d not found [UUID: %s]\n",
2090 spanid, chanid, (uuid) ? uuid : "N/A");
2091 }
2092 }
2093 case FTDM_SIGEVENT_PROGRESS_MEDIA:
2094 {
2095 if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
2096 channel = switch_core_session_get_channel(session);
2097 switch_channel_mark_pre_answered(channel);
2098 switch_core_session_rwunlock(session);
2099 } else {
2100 const char *uuid = ftdm_channel_get_uuid(sigmsg->channel, 0);
2101
2102 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session for channel %d:%d not found [UUID: %s]\n",
2103 spanid, chanid, (uuid) ? uuid : "N/A");
2104 }
2105 }
2106 break;
2107 case FTDM_SIGEVENT_PROGRESS:
2108 {
2109 if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
2110 channel = switch_core_session_get_channel(session);
2111 switch_channel_mark_ring_ready(channel);
2112 switch_core_session_rwunlock(session);
2113 } else {
2114 const char *uuid = ftdm_channel_get_uuid(sigmsg->channel, 0);
2115
2116 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session for channel %d:%d not found [UUID: %s]\n",
2117 spanid, chanid, (uuid) ? uuid : "N/A");
2118 }
2119 }
2120 break;
2121 case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
2122 {
2123 ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus;
2124 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to :%s\n",
2125 spanid, chanid, ftdm_signaling_status2str(sigstatus));
2126 }
2127 break;
2128 default:
2129 {
2130 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled msg type %d for channel %d:%d\n",
2131 sigmsg->event_id, spanid, chanid);
2132 }
2133 break;
2134 }
2135
2136 return FTDM_SUCCESS;
2137 }
2138
2139 static FIO_SIGNAL_CB_FUNCTION(on_analog_signal)
2140 {
2141 uint32_t spanid, chanid;
2142 ftdm_chan_type_t type;
2143 switch_status_t status = SWITCH_STATUS_FALSE;
2144
2145 spanid = ftdm_channel_get_span_id(sigmsg->channel);
2146 chanid = ftdm_channel_get_span_id(sigmsg->channel);
2147 type = ftdm_channel_get_type(sigmsg->channel);
2148
2149 if (on_common_signal(sigmsg) == FTDM_BREAK) {
2150 return FTDM_SUCCESS;
2151 }
2152
2153 switch (type) {
2154 case FTDM_CHAN_TYPE_FXO:
2155 case FTDM_CHAN_TYPE_EM:
2156 {
2157 status = on_fxo_signal(sigmsg);
2158 }
2159 break;
2160 case FTDM_CHAN_TYPE_FXS:
2161 {
2162 status = on_fxs_signal(sigmsg);
2163 }
2164 break;
2165 default:
2166 {
2167 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled analog channel type %d for channel %d:%d\n",
2168 type, spanid, chanid);
2169 }
2170 break;
2171 }
2172
2173 return status;
2174 }
2175
2176 static void ftdm_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
2177 {
2178 char *data = NULL;
2179 va_list ap;
2180
2181 va_start(ap, fmt);
2182
2183 if (switch_vasprintf(&data, fmt, ap) != -1) {
2184 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, (char *)func, line, NULL, level, "%s", data);
2185 }
2186 if (data) free(data);
2187 va_end(ap);
2188
2189 }
2190
2191 static uint32_t enable_analog_option(const char *str, uint32_t current_options)
2192 {
2193 if (!strcasecmp(str, "3-way")) {
2194 current_options |= ANALOG_OPTION_3WAY;
2195 current_options &= ~ANALOG_OPTION_CALL_SWAP;
2196 } else if (!strcasecmp(str, "call-swap")) {
2197 current_options |= ANALOG_OPTION_CALL_SWAP;
2198 current_options &= ~ANALOG_OPTION_3WAY;
2199 }
2200
2201 return current_options;
2202
2203 }
2204
2205
2206
2207
2208 static int add_config_list_nodes(switch_xml_t swnode, ftdm_conf_node_t *rootnode,
2209 const char *list_name, const char *list_element_name,
2210 const char *sub_list_name, const char *sub_list_element_name)
2211 {
2212 char *var, *val;
2213 switch_xml_t list;
2214 switch_xml_t element;
2215 switch_xml_t param;
2216
2217 ftdm_conf_node_t *n_list;
2218 ftdm_conf_node_t *n_element;
2219
2220 list = switch_xml_child(swnode, list_name);
2221 if (!list) {
2222 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no list %s found\n", list_name);
2223 return -1;
2224 }
2225
2226 if ((FTDM_SUCCESS != ftdm_conf_node_create(list_name, &n_list, rootnode))) {
2227 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node\n", list_name);
2228 return -1;
2229 }
2230
2231 for (element = switch_xml_child(list, list_element_name); element; element = element->next) {
2232 char *element_name = (char *) switch_xml_attr(element, "name");
2233
2234 if (!element_name) {
2235 continue;
2236 }
2237
2238 if ((FTDM_SUCCESS != ftdm_conf_node_create(list_element_name, &n_element, n_list))) {
2239 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node for %s\n", list_element_name, element_name);
2240 return -1;
2241 }
2242 ftdm_conf_node_add_param(n_element, "name", element_name);
2243
2244 for (param = switch_xml_child(element, "param"); param; param = param->next) {
2245 var = (char *) switch_xml_attr_soft(param, "name");
2246 val = (char *) switch_xml_attr_soft(param, "value");
2247 ftdm_conf_node_add_param(n_element, var, val);
2248 }
2249
2250 if (sub_list_name && sub_list_element_name) {
2251 if (add_config_list_nodes(element, n_element, sub_list_name, sub_list_element_name, NULL, NULL)) {
2252 return -1;
2253 }
2254 }
2255 }
2256
2257 return 0;
2258 }
2259
2260 static ftdm_conf_node_t *get_ss7_config_node(switch_xml_t cfg, const char *confname)
2261 {
2262 switch_xml_t signode, ss7configs, isup;
2263 ftdm_conf_node_t *rootnode;
2264
2265
2266 rootnode = switch_core_hash_find(globals.ss7_configs, confname);
2267 if (rootnode) {
2268 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ss7 config %s was found in the hash already\n", confname);
2269 return rootnode;
2270 }
2271 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "not found %s config in hash, searching in xml ...\n", confname);
2272
2273 signode = switch_xml_child(cfg, "signaling_configs");
2274 if (!signode) {
2275 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not found 'signaling_configs' XML config section\n");
2276 return NULL;
2277 }
2278
2279 ss7configs = switch_xml_child(signode, "sngss7_configs");
2280 if (!ss7configs) {
2281 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not found 'sngss7_configs' XML config section\n");
2282 return NULL;
2283 }
2284
2285
2286 for (isup = switch_xml_child(ss7configs, "sng_isup"); isup; isup = isup->next) {
2287 char *name = (char *) switch_xml_attr(isup, "name");
2288 if (!name) {
2289 continue;
2290 }
2291 if (!strcasecmp(name, confname)) {
2292 break;
2293 }
2294 }
2295
2296 if (!isup) {
2297 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not found '%s' sng_isup XML config section\n", confname);
2298 return NULL;
2299 }
2300
2301
2302 if ((FTDM_SUCCESS != ftdm_conf_node_create("sng_isup", &rootnode, NULL))) {
2303 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create root node for sng_isup config %s\n", confname);
2304 return NULL;
2305 }
2306
2307
2308 if (add_config_list_nodes(isup, rootnode, "mtp_linksets", "mtp_linkset", "mtp_links", "mtp_link")) {
2309 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp_linksets for sng_isup config %s\n", confname);
2310 ftdm_conf_node_destroy(rootnode);
2311 return NULL;
2312 }
2313
2314
2315 if (add_config_list_nodes(isup, rootnode, "mtp_routes", "mtp_route", NULL, NULL)) {
2316 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp_routes for sng_isup config %s\n", confname);
2317 ftdm_conf_node_destroy(rootnode);
2318 return NULL;
2319 }
2320
2321
2322 if (add_config_list_nodes(isup, rootnode, "isup_interfaces", "isup_interface", NULL, NULL)) {
2323 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process isup_interfaces for sng_isup config %s\n", confname);
2324 ftdm_conf_node_destroy(rootnode);
2325 return NULL;
2326 }
2327
2328 switch_core_hash_insert(globals.ss7_configs, confname, rootnode);
2329
2330 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Added SS7 node configuration %s\n", confname);
2331 return rootnode;
2332 }
2333
2334 static int add_profile_parameters(switch_xml_t cfg, const char *profname, ftdm_conf_parameter_t *parameters, int len)
2335 {
2336 switch_xml_t profnode, profile, param;
2337 int paramindex = 0;
2338
2339 profnode = switch_xml_child(cfg, "config_profiles");
2340 if (!profnode) {
2341 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "cannot find profile '%s', there is no 'config_profiles' XML section\n", profname);
2342 return 0;
2343 }
2344
2345
2346 for (profile = switch_xml_child(profnode, "profile"); profile; profile = profile->next) {
2347 char *name = (char *) switch_xml_attr(profile, "name");
2348 if (!name) {
2349 continue;
2350 }
2351 if (!strcasecmp(name, profname)) {
2352 break;
2353 }
2354 }
2355
2356 if (!profile) {
2357 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to find profile '%s'\n", profname);
2358 return 0;
2359 }
2360
2361 for (param = switch_xml_child(profile, "param"); param; param = param->next) {
2362 char *var = (char *) switch_xml_attr_soft(param, "name");
2363 char *val = (char *) switch_xml_attr_soft(param, "value");
2364 if (!var || !val) {
2365 continue;
2366 }
2367 parameters[paramindex].var = var;
2368 parameters[paramindex].val = val;
2369 paramindex++;
2370 }
2371
2372 return paramindex;
2373 }
2374
2375 static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans)
2376 {
2377 switch_xml_t myspan, param;
2378
2379 for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
2380 ftdm_status_t zstatus = FTDM_FAIL;
2381 const char *context = "default";
2382 const char *dialplan = "XML";
2383 ftdm_conf_parameter_t spanparameters[30];
2384 char *id = (char *) switch_xml_attr(myspan, "id");
2385 char *name = (char *) switch_xml_attr(myspan, "name");
2386 char *configname = (char *) switch_xml_attr(myspan, "cfgprofile");
2387 ftdm_span_t *span = NULL;
2388 uint32_t span_id = 0;
2389 unsigned paramindex = 0;
2390
2391 if (!name && !id) {
2392 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sangoma isdn span missing required attribute 'id' or 'name', skipping ...\n");
2393 continue;
2394 }
2395
2396 if (name) {
2397 zstatus = ftdm_span_find_by_name(name, &span);
2398 } else {
2399 if (switch_is_number(id)) {
2400 span_id = atoi(id);
2401 zstatus = ftdm_span_find(span_id, &span);
2402 }
2403
2404 if (zstatus != FTDM_SUCCESS) {
2405 zstatus = ftdm_span_find_by_name(id, &span);
2406 }
2407 }
2408
2409 if (zstatus != FTDM_SUCCESS) {
2410 ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
2411 continue;
2412 }
2413
2414 if (!span_id) {
2415 span_id = ftdm_span_get_id(span);
2416 }
2417
2418 memset(spanparameters, 0, sizeof(spanparameters));
2419 paramindex = 0;
2420
2421 if (configname) {
2422 paramindex = add_profile_parameters(cfg, configname, spanparameters, ftdm_array_len(spanparameters));
2423 if (paramindex) {
2424 ftdm_log(FTDM_LOG_DEBUG, "Added %d parameters from profile %s for span %d\n", paramindex, configname, span_id);
2425 }
2426 }
2427
2428
2429 SPAN_CONFIG[span_id].limit_backend = "hash";
2430 SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT;
2431
2432 for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
2433 char *var = (char *) switch_xml_attr_soft(param, "name");
2434 char *val = (char *) switch_xml_attr_soft(param, "value");
2435
2436 if (ftdm_array_len(spanparameters) == paramindex) {
2437 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many parameters for ss7 span, ignoring any parameter after %s\n", var);
2438 break;
2439 }
2440
2441 if (!strcasecmp(var, "context")) {
2442 context = val;
2443 } else if (!strcasecmp(var, "dialplan")) {
2444 dialplan = val;
2445 } else if (!strcasecmp(var, "call_limit_backend")) {
2446 SPAN_CONFIG[span_id].limit_backend = val;
2447 ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id);
2448 } else if (!strcasecmp(var, "call_limit_rate")) {
2449 int calls;
2450 int seconds;
2451 if (sscanf(val, "%d/%d", &calls, &seconds) != 2) {
2452 ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var);
2453 } else {
2454 if (calls < 1 || seconds < 1) {
2455 ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, minimum call limit must be 1 per second\n", var);
2456 } else {
2457 SPAN_CONFIG[span_id].limit_calls = calls;
2458 SPAN_CONFIG[span_id].limit_seconds = seconds;
2459 }
2460 }
2461 } else if (!strcasecmp(var, "call_limit_reset_event")) {
2462 if (!strcasecmp(val, "answer")) {
2463 SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER;
2464 } else {
2465 ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, only accepted event is 'answer'\n", var);
2466 }
2467 } else {
2468 spanparameters[paramindex].var = var;
2469 spanparameters[paramindex].val = val;
2470 paramindex++;
2471 }
2472 }
2473
2474 if (ftdm_configure_span_signaling(span,
2475 "sangoma_isdn",
2476 on_clear_channel_signal,
2477 spanparameters) != FTDM_SUCCESS) {
2478 ftdm_log(FTDM_LOG_ERROR, "Error configuring Sangoma ISDN FreeTDM span %d\n", span_id);
2479 continue;
2480 }
2481 SPAN_CONFIG[span_id].span = span;
2482 switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
2483 switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
2484 switch_copy_string(SPAN_CONFIG[span_id].type, "Sangoma (ISDN)", sizeof(SPAN_CONFIG[span_id].type));
2485 ftdm_log(FTDM_LOG_DEBUG, "Configured Sangoma ISDN FreeTDM span %d\n", span_id);
2486 ftdm_span_start(span);
2487 }
2488 }
2489
2490 static switch_status_t load_config(void)
2491 {
2492 const char *cf = "freetdm.conf";
2493 switch_xml_t cfg, xml, settings, param, spans, myspan;
2494 ftdm_conf_node_t *ss7confnode = NULL;
2495 ftdm_span_t *boost_spans[FTDM_MAX_PHYSICAL_SPANS_PER_LOGICAL_SPAN];
2496 ftdm_span_t *boost_span = NULL;
2497 unsigned boosti = 0;
2498 unsigned int i = 0;
2499 ftdm_channel_t *fchan = NULL;
2500 ftdm_iterator_t *chaniter = NULL;
2501 ftdm_iterator_t *curr = NULL;
2502
2503 memset(boost_spans, 0, sizeof(boost_spans));
2504 memset(&globals, 0, sizeof(globals));
2505 switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool);
2506 if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
2507 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
2508 return SWITCH_STATUS_TERM;
2509 }
2510
2511 if ((settings = switch_xml_child(cfg, "settings"))) {
2512 for (param = switch_xml_child(settings, "param"); param; param = param->next) {
2513 char *var = (char *) switch_xml_attr_soft(param, "name");
2514 char *val = (char *) switch_xml_attr_soft(param, "value");
2515
2516 if (!strcasecmp(var, "debug")) {
2517 globals.debug = atoi(val);
2518 } else if (!strcasecmp(var, "hold-music")) {
2519 switch_set_string(globals.hold_music, val);
2520 } else if (!strcasecmp(var, "crash-on-assert")) {
2521 globals.crash_on_assert = switch_true(val);
2522 } else if (!strcasecmp(var, "sip-headers")) {
2523 globals.sip_headers = switch_true(val);
2524 } else if (!strcasecmp(var, "enable-analog-option")) {
2525 globals.analog_options = enable_analog_option(val, globals.analog_options);
2526 }
2527 }
2528 }
2529
2530 if ((spans = switch_xml_child(cfg, "sangoma_pri_spans"))) {
2531 parse_bri_pri_spans(cfg, spans);
2532 }
2533
2534 if ((spans = switch_xml_child(cfg, "sangoma_bri_spans"))) {
2535 parse_bri_pri_spans(cfg, spans);
2536 }
2537
2538 switch_core_hash_init(&globals.ss7_configs, module_pool);
2539 if ((spans = switch_xml_child(cfg, "sangoma_ss7_spans"))) {
2540 for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
2541 ftdm_status_t zstatus = FTDM_FAIL;
2542 const char *context = "default";
2543 const char *dialplan = "XML";
2544 ftdm_conf_parameter_t spanparameters[30];
2545 char *id = (char *) switch_xml_attr(myspan, "id");
2546 char *name = (char *) switch_xml_attr(myspan, "name");
2547 char *configname = (char *) switch_xml_attr(myspan, "config");
2548 ftdm_span_t *span = NULL;
2549 uint32_t span_id = 0;
2550 unsigned paramindex = 0;
2551 if (!name && !id) {
2552 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ss7 span missing required attribute 'id' or 'name', skipping ...\n");
2553 continue;
2554 }
2555 if (!configname) {
2556 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ss7 span missing required attribute, skipping ...\n");
2557 continue;
2558 }
2559 if (name) {
2560 zstatus = ftdm_span_find_by_name(name, &span);
2561 } else {
2562 if (switch_is_number(id)) {
2563 span_id = atoi(id);
2564 zstatus = ftdm_span_find(span_id, &span);
2565 }
2566
2567 if (zstatus != FTDM_SUCCESS) {
2568 zstatus = ftdm_span_find_by_name(id, &span);
2569 }
2570 }
2571
2572 if (zstatus != FTDM_SUCCESS) {
2573 ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
2574 continue;
2575 }
2576
2577 if (!span_id) {
2578 span_id = ftdm_span_get_id(span);
2579 }
2580
2581 ss7confnode = get_ss7_config_node(cfg, configname);
2582 if (!ss7confnode) {
2583 ftdm_log(FTDM_LOG_ERROR, "Error finding ss7config '%s' for FreeTDM span id: %s\n", configname, switch_str_nil(id));
2584 continue;
2585 }
2586
2587 memset(spanparameters, 0, sizeof(spanparameters));
2588 paramindex = 0;
2589 spanparameters[paramindex].var = "confnode";
2590 spanparameters[paramindex].ptr = ss7confnode;
2591 paramindex++;
2592 for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
2593 char *var = (char *) switch_xml_attr_soft(param, "name");
2594 char *val = (char *) switch_xml_attr_soft(param, "value");
2595
2596 if (sizeof(spanparameters)/sizeof(spanparameters[0]) == paramindex) {
2597 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many parameters for ss7 span, ignoring any parameter after %s\n", var);
2598 break;
2599 }
2600
2601 if (!strcasecmp(var, "context")) {
2602 context = val;
2603 } else if (!strcasecmp(var, "dialplan")) {
2604 dialplan = val;
2605 } else {
2606 spanparameters[paramindex].var = var;
2607 spanparameters[paramindex].val = val;
2608 paramindex++;
2609 }
2610 }
2611
2612 if (ftdm_configure_span_signaling(span,
2613 "sangoma_ss7",
2614 on_clear_channel_signal,
2615 spanparameters) != FTDM_SUCCESS) {
2616 ftdm_log(FTDM_LOG_ERROR, "Error configuring ss7 FreeTDM span %d\n", span_id);
2617 continue;
2618 }
2619 SPAN_CONFIG[span_id].span = span;
2620 switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
2621 switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
2622 switch_copy_string(SPAN_CONFIG[span_id].type, "Sangoma (SS7)", sizeof(SPAN_CONFIG[span_id].type));
2623 ftdm_log(FTDM_LOG_DEBUG, "Configured ss7 FreeTDM span %d with config node %s\n", span_id, configname);
2624 ftdm_span_start(span);
2625 }
2626 }
2627
2628 if ((spans = switch_xml_child(cfg, "analog_spans"))) {
2629 for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
2630 char *id = (char *) switch_xml_attr(myspan, "id");
2631 char *name = (char *) switch_xml_attr(myspan, "name");
2632 ftdm_status_t zstatus = FTDM_FAIL;
2633 const char *context = "default";
2634 const char *dialplan = "XML";
2635 const char *tonegroup = NULL;
2636 char *digit_timeout = NULL;
2637 char *max_digits = NULL;
2638 char *hotline = NULL;
2639 char *dial_regex = NULL;
2640 char *hold_music = NULL;
2641 char *fail_dial_regex = NULL;
2642 const char *enable_callerid = "true";
2643 int callwaiting = 1;
2644
2645 uint32_t span_id = 0, to = 0, max = 0;
2646 ftdm_span_t *span = NULL;
2647 analog_option_t analog_options = ANALOG_OPTION_NONE;
2648
2649 if (name) {
2650 zstatus = ftdm_span_find_by_name(name, &span);
2651 } else {
2652 if (switch_is_number(id)) {
2653 span_id = atoi(id);
2654 zstatus = ftdm_span_find(span_id, &span);
2655 }
2656
2657 if (zstatus != FTDM_SUCCESS) {
2658 zstatus = ftdm_span_find_by_name(id, &span);
2659 }
2660 }
2661
2662 if (zstatus != FTDM_SUCCESS) {
2663 ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
2664 continue;
2665 }
2666
2667 if (!span_id) {
2668 span_id = ftdm_span_get_id(span);
2669 }
2670
2671
2672 SPAN_CONFIG[span_id].limit_backend = "hash";
2673 SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT;
2674
2675 for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
2676 char *var = (char *) switch_xml_attr_soft(param, "name");
2677 char *val = (char *) switch_xml_attr_soft(param, "value");
2678
2679 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "analog_spans var = %s\n", var);
2680 if (!strcasecmp(var, "tonegroup")) {
2681 tonegroup = val;
2682 } else if (!strcasecmp(var, "digit_timeout") || !strcasecmp(var, "digit-timeout")) {
2683 digit_timeout = val;
2684 } else if (!strcasecmp(var, "context")) {
2685 context = val;
2686 } else if (!strcasecmp(var, "dialplan")) {
2687 dialplan = val;
2688 } else if (!strcasecmp(var, "call_limit_backend")) {
2689 SPAN_CONFIG[span_id].limit_backend = val;
2690 ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id);
2691 } else if (!strcasecmp(var, "call_limit_rate")) {
2692 int calls;
2693 int seconds;
2694 if (sscanf(val, "%d/%d", &calls, &seconds) != 2) {
2695 ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var);
2696 } else {
2697 if (calls < 1 || seconds < 1) {
2698 ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, minimum call limit must be 1 per second\n", var);
2699 } else {
2700 SPAN_CONFIG[span_id].limit_calls = calls;
2701 SPAN_CONFIG[span_id].limit_seconds = seconds;
2702 }
2703 }
2704 } else if (!strcasecmp(var, "call_limit_reset_event")) {
2705 if (!strcasecmp(val, "answer")) {
2706 SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER;
2707 } else {
2708 ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, only accepted event is 'answer'\n", var);
2709 }
2710 } else if (!strcasecmp(var, "dial-regex")) {
2711 dial_regex = val;
2712 } else if (!strcasecmp(var, "enable-callerid")) {
2713 enable_callerid = val;
2714 } else if (!strcasecmp(var, "fail-dial-regex")) {
2715 fail_dial_regex = val;
2716 } else if (!strcasecmp(var, "hold-music")) {
2717 hold_music = val;
2718 } else if (!strcasecmp(var, "max_digits") || !strcasecmp(var, "max-digits")) {
2719 max_digits = val;
2720 } else if (!strcasecmp(var, "hotline")) {
2721 hotline = val;
2722 } else if (!strcasecmp(var, "callwaiting")) {
2723 callwaiting = switch_true(val) ? 1 : 0;
2724 } else if (!strcasecmp(var, "enable-analog-option")) {
2725 analog_options = enable_analog_option(val, analog_options);
2726 }
2727 }
2728
2729 if (!id && !name) {
2730 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required param 'id'\n");
2731 continue;
2732 }
2733
2734 if (!tonegroup) {
2735 tonegroup = "us";
2736 }
2737
2738 if (digit_timeout) {
2739 to = atoi(digit_timeout);
2740 }
2741
2742 if (max_digits) {
2743 max = atoi(max_digits);
2744 }
2745
2746 if (name) {
2747 zstatus = ftdm_span_find_by_name(name, &span);
2748 } else {
2749 if (switch_is_number(id)) {
2750 span_id = atoi(id);
2751 zstatus = ftdm_span_find(span_id, &span);
2752 }
2753
2754 if (zstatus != FTDM_SUCCESS) {
2755 zstatus = ftdm_span_find_by_name(id, &span);
2756 }
2757 }
2758
2759 if (zstatus != FTDM_SUCCESS) {
2760 ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
2761 continue;
2762 }
2763
2764 if (!span_id) {
2765 span_id = ftdm_span_get_id(span);
2766 }
2767
2768 if (ftdm_configure_span(span, "analog", on_analog_signal,
2769 "tonemap", tonegroup,
2770 "digit_timeout", &to,
2771 "max_dialstr", &max,
2772 "hotline", hotline ? hotline : "",
2773 "enable_callerid", enable_callerid,
2774 "callwaiting", &callwaiting,
2775 FTDM_TAG_END) != FTDM_SUCCESS) {
2776 ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM analog span %s\n", ftdm_span_get_name(span));
2777 continue;
2778 }
2779
2780 SPAN_CONFIG[span_id].span = span;
2781 switch_set_string(SPAN_CONFIG[span_id].context, context);
2782 switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan);
2783 SPAN_CONFIG[span_id].analog_options = analog_options | globals.analog_options;
2784
2785 chaniter = ftdm_span_get_chan_iterator(span, NULL);
2786 curr = chaniter;
2787 for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
2788 fchan = ftdm_iterator_current(curr);
2789 ftdm_channel_set_private(fchan, &SPAN_CONFIG[span_id].pvts[i]);
2790 }
2791 ftdm_iterator_free(chaniter);
2792
2793 if (dial_regex) {
2794 switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex);
2795 }
2796
2797 if (fail_dial_regex) {
2798 switch_set_string(SPAN_CONFIG[span_id].fail_dial_regex, fail_dial_regex);
2799 }
2800
2801 if (hold_music) {
2802 switch_set_string(SPAN_CONFIG[span_id].hold_music, hold_music);
2803 }
2804 switch_copy_string(SPAN_CONFIG[span_id].type, "analog", sizeof(SPAN_CONFIG[span_id].type));
2805 ftdm_span_start(span);
2806 }
2807 }
2808
2809 if ((spans = switch_xml_child(cfg, "analog_em_spans"))) {
2810 for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
2811 char *id = (char *) switch_xml_attr(myspan, "id");
2812 char *name = (char *) switch_xml_attr(myspan, "name");
2813 ftdm_status_t zstatus = FTDM_FAIL;
2814 const char *context = "default";
2815 const char *dialplan = "XML";
2816 const char *tonegroup = NULL;
2817 char *digit_timeout = NULL;
2818 char *max_digits = NULL;
2819 char *dial_regex = NULL;
2820 char *hold_music = NULL;
2821 char *fail_dial_regex = NULL;
2822 uint32_t span_id = 0, to = 0, max = 0;
2823 ftdm_span_t *span = NULL;
2824 analog_option_t analog_options = ANALOG_OPTION_NONE;
2825
2826 for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
2827 char *var = (char *) switch_xml_attr_soft(param, "name");
2828 char *val = (char *) switch_xml_attr_soft(param, "value");
2829
2830 if (!strcasecmp(var, "tonegroup")) {
2831 tonegroup = val;
2832 } else if (!strcasecmp(var, "digit_timeout") || !strcasecmp(var, "digit-timeout")) {
2833 digit_timeout = val;
2834 } else if (!strcasecmp(var, "context")) {
2835 context = val;
2836 } else if (!strcasecmp(var, "dialplan")) {
2837 dialplan = val;
2838 } else if (!strcasecmp(var, "dial-regex")) {
2839 dial_regex = val;
2840 } else if (!strcasecmp(var, "fail-dial-regex")) {
2841 fail_dial_regex = val;
2842 } else if (!strcasecmp(var, "hold-music")) {
2843 hold_music = val;
2844 } else if (!strcasecmp(var, "max_digits") || !strcasecmp(var, "max-digits")) {
2845 max_digits = val;
2846 } else if (!strcasecmp(var, "enable-analog-option")) {
2847 analog_options = enable_analog_option(val, analog_options);
2848 }
2849 }
2850
2851 if (!id && !name) {
2852 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required param 'id'\n");
2853 continue;
2854 }
2855
2856
2857 if (!tonegroup) {
2858 tonegroup = "us";
2859 }
2860
2861 if (digit_timeout) {
2862 to = atoi(digit_timeout);
2863 }
2864
2865 if (max_digits) {
2866 max = atoi(max_digits);
2867 }
2868
2869
2870 if (name) {
2871 zstatus = ftdm_span_find_by_name(name, &span);
2872 } else {
2873 if (switch_is_number(id)) {
2874 span_id = atoi(id);
2875 zstatus = ftdm_span_find(span_id, &span);
2876 }
2877
2878 if (zstatus != FTDM_SUCCESS) {
2879 zstatus = ftdm_span_find_by_name(id, &span);
2880 }
2881 }
2882
2883 if (zstatus != FTDM_SUCCESS) {
2884 ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
2885 continue;
2886 }
2887
2888 if (!span_id) {
2889 span_id = ftdm_span_get_id(span);
2890 }
2891
2892
2893 if (ftdm_configure_span(span, "analog_em", on_analog_signal,
2894 "tonemap", tonegroup,
2895 "digit_timeout", &to,
2896 "max_dialstr", &max,
2897 FTDM_TAG_END) != FTDM_SUCCESS) {
2898 ftdm_log(FTDM_LOG_ERROR, "Error starting FreeTDM span %d\n", span_id);
2899 continue;
2900 }
2901
2902 SPAN_CONFIG[span_id].span = span;
2903 switch_set_string(SPAN_CONFIG[span_id].context, context);
2904 switch_set_string(SPAN_CONFIG[span_id].dialplan, dialplan);
2905 SPAN_CONFIG[span_id].analog_options = analog_options | globals.analog_options;
2906
2907 if (dial_regex) {
2908 switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex);
2909 }
2910
2911 if (fail_dial_regex) {
2912 switch_set_string(SPAN_CONFIG[span_id].fail_dial_regex, fail_dial_regex);
2913 }
2914
2915 if (hold_music) {
2916 switch_set_string(SPAN_CONFIG[span_id].hold_music, hold_music);
2917 }
2918 switch_copy_string(SPAN_CONFIG[span_id].type, "analog_em", sizeof(SPAN_CONFIG[span_id].type));
2919 ftdm_span_start(span);
2920 }
2921 }
2922
2923 if ((spans = switch_xml_child(cfg, "pri_spans"))) {
2924 for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
2925 char *id = (char *) switch_xml_attr(myspan, "id");
2926 char *name = (char *) switch_xml_attr(myspan, "name");
2927 ftdm_status_t zstatus = FTDM_FAIL;
2928 const char *context = "default";
2929 const char *dialplan = "XML";
2930
2931
2932 char *mode = NULL;
2933 char *dialect = NULL;
2934 uint32_t span_id = 0;
2935 ftdm_span_t *span = NULL;
2936 const char *tonegroup = NULL;
2937 char *digit_timeout = NULL;
2938 const char *opts = "none";
2939 uint32_t to = 0;
2940 int q921loglevel = -1;
2941 int q931loglevel = -1;
2942
2943
2944
2945
2946 for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
2947 char *var = (char *) switch_xml_attr_soft(param, "name");
2948 char *val = (char *) switch_xml_attr_soft(param, "value");
2949
2950 if (!strcasecmp(var, "tonegroup")) {
2951 tonegroup = val;
2952 } else if (!strcasecmp(var, "mode")) {
2953 mode = val;
2954 } else if (!strcasecmp(var, "dialect")) {
2955 dialect = val;
2956 } else if (!strcasecmp(var, "q921loglevel")) {
2957 if ((q921loglevel = switch_log_str2level(val)) == SWITCH_LOG_INVALID) {
2958 q921loglevel = -1;
2959 }
2960 } else if (!strcasecmp(var, "q931loglevel")) {
2961 if ((q931loglevel = switch_log_str2level(val)) == SWITCH_LOG_INVALID) {
2962 q931loglevel = -1;
2963 }
2964 } else if (!strcasecmp(var, "context")) {
2965 context = val;
2966 } else if (!strcasecmp(var, "opts")) {
2967 opts = val;
2968 } else if (!strcasecmp(var, "dialplan")) {
2969 dialplan = val;
2970 } else if (!strcasecmp(var, "digit_timeout") || !strcasecmp(var, "digit-timeout")) {
2971 digit_timeout = val;
2972 }
2973 }
2974
2975 if (!id && !name) {
2976 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required param 'id'\n");
2977 continue;
2978 }
2979
2980 if (name) {
2981 zstatus = ftdm_span_find_by_name(name, &span);
2982 } else {
2983 if (switch_is_number(id)) {
2984 span_id = atoi(id);
2985 zstatus = ftdm_span_find(span_id, &span);
2986 }
2987
2988 if (zstatus != FTDM_SUCCESS) {
2989 zstatus = ftdm_span_find_by_name(id, &span);
2990 }
2991 }
2992
2993 if (digit_timeout) {
2994 to = atoi(digit_timeout);
2995 }
2996
2997 if (zstatus != FTDM_SUCCESS) {
2998 ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
2999 continue;
3000 }
3001
3002 if (!span_id) {
3003 span_id = ftdm_span_get_id(span);
3004 }
3005
3006 if (!tonegroup) {
3007 tonegroup = "us";
3008 }
3009
3010 if (ftdm_configure_span(span, "isdn", on_clear_channel_signal,
3011 "mode", mode,
3012 "dialect", dialect,
3013 "digit_timeout", &to,
3014 "opts", opts,
3015 "tonemap", tonegroup,
3016 "q921loglevel", q921loglevel,
3017 "q931loglevel", q931loglevel,
3018 FTDM_TAG_END) != FTDM_SUCCESS) {
3019 ftdm_log(FTDM_LOG_ERROR, "Error starting FreeTDM span %d mode: %s dialect: %s error: %s\n", span_id,
3020 mode, dialect, ftdm_span_get_last_error(span));
3021 continue;
3022 }
3023
3024 SPAN_CONFIG[span_id].span = span;
3025 switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
3026 switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
3027 switch_copy_string(SPAN_CONFIG[span_id].type, "isdn", sizeof(SPAN_CONFIG[span_id].type));
3028
3029 ftdm_span_start(span);
3030 }
3031 }
3032
3033 if ((spans = switch_xml_child(cfg, "pritap_spans"))) {
3034 for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
3035
3036 char *name = (char *) switch_xml_attr(myspan, "name");
3037
3038 ftdm_status_t zstatus = FTDM_FAIL;
3039 unsigned paramindex = 0;
3040 ftdm_conf_parameter_t spanparameters[10];
3041 const char *context = "default";
3042 const char *dialplan = "XML";
3043 ftdm_span_t *span = NULL;
3044 int span_id = 0;
3045
3046 if (!name) {
3047 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required attribute 'name'\n");
3048 continue;
3049 }
3050
3051 for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
3052 char *var = (char *) switch_xml_attr_soft(param, "name");
3053 char *val = (char *) switch_xml_attr_soft(param, "value");
3054
3055 if (!strcasecmp(var, "context")) {
3056 context = val;
3057 } else if (!strcasecmp(var, "dialplan")) {
3058 dialplan = val;
3059 } else {
3060 spanparameters[paramindex].var = var;
3061 spanparameters[paramindex].val = val;
3062 paramindex++;
3063 }
3064 }
3065
3066 zstatus = ftdm_span_find_by_name(name, &span);
3067 if (zstatus != FTDM_SUCCESS) {
3068 ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span %s\n", name);
3069 continue;
3070 }
3071
3072 span_id = ftdm_span_get_id(span);
3073 if (ftdm_configure_span_signaling(span, "pritap", on_clear_channel_signal, spanparameters) != FTDM_SUCCESS) {
3074 ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM span %s\n", name);
3075 continue;
3076 }
3077
3078 SPAN_CONFIG[span_id].span = span;
3079 switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
3080 switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
3081 switch_copy_string(SPAN_CONFIG[span_id].type, "isdn", sizeof(SPAN_CONFIG[span_id].type));
3082
3083 ftdm_span_start(span);
3084 }
3085 }
3086
3087
3088 if ((spans = switch_xml_child(cfg, "libpri_spans"))) {
3089 for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
3090 char *id = (char *) switch_xml_attr(myspan, "id");
3091 char *name = (char *) switch_xml_attr(myspan, "name");
3092 ftdm_status_t zstatus = FTDM_FAIL;
3093 const char *context = "default";
3094 const char *dialplan = "XML";
3095
3096 const char *o_node = "cpe";
3097 const char *o_switch = "dms100";
3098 const char *o_dp = "unknown";
3099 const char *o_l1 = "ulaw";
3100 const char *o_debug = "none";
3101 const char* opts = "none";
3102
3103 uint32_t span_id = 0;
3104 ftdm_span_t *span = NULL;
3105
3106
3107 for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
3108 char *var = (char *) switch_xml_attr_soft(param, "name");
3109 char *val = (char *) switch_xml_attr_soft(param, "value");
3110
3111 if (!strcasecmp(var, "node")) {
3112 o_node = val;
3113 } else if (!strcasecmp(var, "switch")) {
3114 o_switch = val;
3115 } else if (!strcasecmp(var, "dp")) {
3116 o_dp = val;
3117 } else if (!strcasecmp(var, "l1")) {
3118 o_l1 = val;
3119 } else if (!strcasecmp(var, "debug")) {
3120 o_debug = val;
3121 } else if (!strcasecmp(var, "context")) {
3122 context = val;
3123 } else if (!strcasecmp(var, "opts")) {
3124 opts = val;
3125 } else if (!strcasecmp(var, "dialplan")) {
3126 dialplan = val;
3127 }
3128 }
3129
3130 if (!id && !name) {
3131 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required param 'id'\n");
3132 continue;
3133 }
3134
3135 if (name) {
3136 zstatus = ftdm_span_find_by_name(name, &span);
3137 } else {
3138 if (switch_is_number(id)) {
3139 span_id = atoi(id);
3140 zstatus = ftdm_span_find(span_id, &span);
3141 }
3142
3143 if (zstatus != FTDM_SUCCESS) {
3144 zstatus = ftdm_span_find_by_name(id, &span);
3145 }
3146 }
3147
3148 if (zstatus != FTDM_SUCCESS) {
3149 ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
3150 continue;
3151 }
3152
3153 if (!span_id) {
3154 span_id = ftdm_span_get_id(span);
3155 }
3156
3157
3158 if (ftdm_configure_span(span, "libpri", on_clear_channel_signal,
3159 "node", o_node,
3160 "switch", o_switch,
3161 "dp", o_dp,
3162 "l1", o_l1,
3163 "debug", o_debug,
3164 "opts", opts,
3165 FTDM_TAG_END) != FTDM_SUCCESS) {
3166 ftdm_log(FTDM_LOG_ERROR, "Error starting FreeTDM span %d node: %s switch: %s dp: %s l1: %s debug: %s error: %s\n",
3167 span_id, switch_str_nil(o_node), switch_str_nil(o_switch), switch_str_nil(o_dp), switch_str_nil(o_l1), switch_str_nil(o_debug),
3168 ftdm_span_get_last_error(span));
3169 continue;
3170 }
3171
3172 SPAN_CONFIG[span_id].span = span;
3173 switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
3174 switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
3175 switch_copy_string(SPAN_CONFIG[span_id].type, "isdn", sizeof(SPAN_CONFIG[span_id].type));
3176
3177 ftdm_span_start(span);
3178 }
3179 }
3180
3181 if ((spans = switch_xml_child(cfg, "boost_spans"))) {
3182 for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
3183 char *id = (char *) switch_xml_attr(myspan, "id");
3184 char *name = (char *) switch_xml_attr(myspan, "name");
3185 char *sigmod = (char *) switch_xml_attr(myspan, "sigmod");
3186 ftdm_status_t zstatus = FTDM_FAIL;
3187 const char *context = "default";
3188 const char *dialplan = "XML";
3189 uint32_t span_id = 0;
3190 ftdm_span_t *span = NULL;
3191 ftdm_conf_parameter_t spanparameters[30];
3192 unsigned paramindex = 0;
3193
3194 if (!id && !name) {
3195 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "boost span requires an id or name as attribute: <span id=ftid|name=ftname>\n");
3196 continue;
3197 }
3198 memset(spanparameters, 0, sizeof(spanparameters));
3199 if (sigmod) {
3200 spanparameters[paramindex].var = "sigmod";
3201 spanparameters[paramindex].val = sigmod;
3202 paramindex++;
3203 }
3204
3205 for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
3206 char *var = (char *) switch_xml_attr_soft(param, "name");
3207 char *val = (char *) switch_xml_attr_soft(param, "value");
3208 if (sizeof(spanparameters)/sizeof(spanparameters[0]) == paramindex) {
3209 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many parameters for boost span, ignoring any parameter after %s\n", var);
3210 break;
3211 }
3212
3213 if (!strcasecmp(var, "context")) {
3214 context = val;
3215 } else if (!strcasecmp(var, "dialplan")) {
3216 dialplan = val;
3217 } else {
3218 spanparameters[paramindex].var = var;
3219 spanparameters[paramindex].val = val;
3220 paramindex++;
3221 }
3222 }
3223
3224 if (name) {
3225 zstatus = ftdm_span_find_by_name(name, &span);
3226 } else {
3227 if (switch_is_number(id)) {
3228 span_id = atoi(id);
3229 zstatus = ftdm_span_find(span_id, &span);
3230 }
3231
3232 if (zstatus != FTDM_SUCCESS) {
3233 zstatus = ftdm_span_find_by_name(id, &span);
3234 }
3235 }
3236
3237 if (zstatus != FTDM_SUCCESS) {
3238 ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
3239 continue;
3240 }
3241
3242 if (!span_id) {
3243 span_id = ftdm_span_get_id(span);
3244 }
3245
3246 if (ftdm_configure_span_signaling(span, "sangoma_boost", on_clear_channel_signal, spanparameters) != FTDM_SUCCESS) {
3247 ftdm_log(FTDM_LOG_ERROR, "Error starting FreeTDM span %d error: %s\n", span_id, ftdm_span_get_last_error(span));
3248 continue;
3249 }
3250
3251 SPAN_CONFIG[span_id].span = span;
3252 switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
3253 switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
3254
3255 switch_copy_string(SPAN_CONFIG[span_id].type, "Sangoma (boost)", sizeof(SPAN_CONFIG[span_id].type));
3256 boost_spans[boosti++] = span;
3257 }
3258 }
3259
3260 if ((spans = switch_xml_child(cfg, "r2_spans"))) {
3261 for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
3262 char *id = (char *) switch_xml_attr(myspan, "id");
3263 char *name = (char *) switch_xml_attr(myspan, "name");
3264 ftdm_status_t zstatus = FTDM_FAIL;
3265
3266
3267 const char *variant = "itu";
3268 const char *category = "national_subscriber";
3269 const char *logdir = "/usr/local/freeswitch/log/";
3270 const char *logging = "notice,warning,error";
3271 const char *advanced_protocol_file = "";
3272
3273
3274 int call_files = 0;
3275 int get_ani_first = -1;
3276 int immediate_accept = -1;
3277 int double_answer = -1;
3278 int skip_category = -1;
3279 int forced_release = -1;
3280 int charge_calls = -1;
3281
3282
3283 int mfback_timeout = -1;
3284 int metering_pulse_timeout = -1;
3285 int allow_collect_calls = -1;
3286 int max_ani = 10;
3287 int max_dnis = 4;
3288
3289
3290 const char *context = "default";
3291 const char *dialplan = "XML";
3292 char *dial_regex = NULL;
3293 char *fail_dial_regex = NULL;
3294 uint32_t span_id = 0;
3295 ftdm_span_t *span = NULL;
3296
3297
3298 for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
3299 char *var = (char *) switch_xml_attr_soft(param, "name");
3300 char *val = (char *) switch_xml_attr_soft(param, "value");
3301
3302
3303 if (!strcasecmp(var, "variant")) {
3304 variant = val;
3305 } else if (!strcasecmp(var, "category")) {
3306 category = val;
3307 } else if (!strcasecmp(var, "logdir")) {
3308 logdir = val;
3309 } else if (!strcasecmp(var, "logging")) {
3310 logging = val;
3311 } else if (!strcasecmp(var, "advanced_protocol_file")) {
3312 advanced_protocol_file = val;
3313
3314
3315 } else if (!strcasecmp(var, "allow_collect_calls")) {
3316 allow_collect_calls = switch_true(val);
3317 } else if (!strcasecmp(var, "immediate_accept")) {
3318 immediate_accept = switch_true(val);
3319 } else if (!strcasecmp(var, "double_answer")) {
3320 double_answer = switch_true(val);
3321 } else if (!strcasecmp(var, "skip_category")) {
3322 skip_category = switch_true(var);
3323 } else if (!strcasecmp(var, "forced_release")) {
3324 forced_release = switch_true(val);
3325 } else if (!strcasecmp(var, "charge_calls")) {
3326 charge_calls = switch_true(val);
3327 } else if (!strcasecmp(var, "get_ani_first")) {
3328 get_ani_first = switch_true(val);
3329 } else if (!strcasecmp(var, "call_files")) {
3330 call_files = switch_true(val);
3331
3332
3333 } else if (!strcasecmp(var, "mfback_timeout")) {
3334 mfback_timeout = atoi(val);
3335 } else if (!strcasecmp(var, "metering_pulse_timeout")) {
3336 metering_pulse_timeout = atoi(val);
3337 } else if (!strcasecmp(var, "max_ani")) {
3338 max_ani = atoi(val);
3339 } else if (!strcasecmp(var, "max_dnis")) {
3340 max_dnis = atoi(val);
3341
3342
3343 } else if (!strcasecmp(var, "context")) {
3344 context = val;
3345 } else if (!strcasecmp(var, "dialplan")) {
3346 dialplan = val;
3347 } else if (!strcasecmp(var, "dial-regex")) {
3348 dial_regex = val;
3349 } else if (!strcasecmp(var, "fail-dial-regex")) {
3350 fail_dial_regex = val;
3351 }
3352 }
3353
3354 if (!id && !name) {
3355 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required param 'id'\n");
3356 continue;
3357 }
3358
3359 if (name) {
3360 zstatus = ftdm_span_find_by_name(name, &span);
3361 } else {
3362 if (switch_is_number(id)) {
3363 span_id = atoi(id);
3364 zstatus = ftdm_span_find(span_id, &span);
3365 }
3366
3367 if (zstatus != FTDM_SUCCESS) {
3368 zstatus = ftdm_span_find_by_name(id, &span);
3369 }
3370 }
3371
3372 if (zstatus != FTDM_SUCCESS) {
3373 ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
3374 continue;
3375 }
3376
3377 if (!span_id) {
3378 span_id = ftdm_span_get_id(span);
3379 }
3380
3381 if (ftdm_configure_span(span, "r2", on_r2_signal,
3382 "variant", variant,
3383 "max_ani", max_ani,
3384 "max_dnis", max_dnis,
3385 "category", category,
3386 "logdir", logdir,
3387 "logging", logging,
3388 "advanced_protocol_file", advanced_protocol_file,
3389 "allow_collect_calls", allow_collect_calls,
3390 "immediate_accept", immediate_accept,
3391 "double_answer", double_answer,
3392 "skip_category", skip_category,
3393 "forced_release", forced_release,
3394 "charge_calls", charge_calls,
3395 "get_ani_first", get_ani_first,
3396 "call_files", call_files,
3397 "mfback_timeout", mfback_timeout,
3398 "metering_pulse_timeout", metering_pulse_timeout,
3399 FTDM_TAG_END) != FTDM_SUCCESS) {
3400 ftdm_log(FTDM_LOG_ERROR, "Error configuring R2 FreeTDM span %d, error: %s\n",
3401 span_id, ftdm_span_get_last_error(span));
3402 continue;
3403 }
3404
3405 if (dial_regex) {
3406 switch_set_string(SPAN_CONFIG[span_id].dial_regex, dial_regex);
3407 }
3408
3409 if (fail_dial_regex) {
3410 switch_set_string(SPAN_CONFIG[span_id].fail_dial_regex, fail_dial_regex);
3411 }
3412
3413 SPAN_CONFIG[span_id].span = span;
3414 switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
3415 switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
3416 switch_copy_string(SPAN_CONFIG[span_id].type, "r2", sizeof(SPAN_CONFIG[span_id].type));
3417
3418 if (ftdm_span_start(span) == FTDM_FAIL) {
3419 ftdm_log(FTDM_LOG_ERROR, "Error starting R2 FreeTDM span %d, error: %s\n", span_id, ftdm_span_get_last_error(span));
3420 continue;
3421 }
3422 }
3423 }
3424
3425
3426
3427 for (i=0 ; i < boosti; i++) {
3428 boost_span = boost_spans[i];
3429 ftdm_log(FTDM_LOG_DEBUG, "Starting boost span %d\n", ftdm_span_get_id(boost_span));
3430 if (ftdm_span_start(boost_span) == FTDM_FAIL) {
3431 ftdm_log(FTDM_LOG_ERROR, "Error starting boost FreeTDM span %d, error: %s\n",
3432 ftdm_span_get_id(boost_span), ftdm_span_get_last_error(boost_span));
3433 continue;
3434 }
3435 }
3436
3437 if (globals.crash_on_assert) {
3438 ftdm_log(FTDM_LOG_WARNING, "Crash on assert enabled\n");
3439 ftdm_global_set_crash_policy(FTDM_CRASH_ON_ASSERT);
3440 }
3441
3442 switch_xml_free(xml);
3443
3444 return SWITCH_STATUS_SUCCESS;
3445 }
3446
3447 void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream)
3448 {
3449 uint32_t span_id;
3450 uint32_t phspan_id, phchan_id;
3451 const char *chan_type;
3452 const char *state;
3453 const char *last_state;
3454 const char *uuid = NULL;
3455 char sessionid[255];
3456 float txgain, rxgain;
3457 switch_core_session_t *session = NULL;
3458 ftdm_alarm_flag_t alarmflag;
3459 ftdm_caller_data_t *caller_data;
3460 ftdm_channel_t *ftdmchan;
3461 ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN;
3462
3463 if (chan_id > ftdm_span_get_chan_count(span)) {
3464 return;
3465 }
3466
3467 strcpy(sessionid, "(none)");
3468 ftdmchan = ftdm_span_get_channel(span, chan_id);
3469 span_id = ftdm_span_get_id(span);
3470
3471 phspan_id = ftdm_channel_get_ph_span_id(ftdmchan);
3472 phchan_id = ftdm_channel_get_ph_id(ftdmchan);
3473 chan_type = ftdm_chan_type2str(ftdm_channel_get_type(ftdmchan));
3474 state = ftdm_channel_get_state_str(ftdmchan);
3475 last_state = ftdm_channel_get_last_state_str(ftdmchan);
3476 ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_RX_GAIN, &rxgain);
3477 ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_TX_GAIN, &txgain);
3478 caller_data = ftdm_channel_get_caller_data(ftdmchan);
3479 ftdm_channel_get_sig_status(ftdmchan, &sigstatus);
3480 ftdm_channel_get_alarms(ftdmchan, &alarmflag);
3481
3482 uuid = ftdm_channel_get_uuid(ftdmchan, 0);
3483 if (!zstr(uuid)) {
3484 if (!(session = switch_core_session_locate(uuid))) {
3485 snprintf(sessionid, sizeof(sessionid), "%s (dead)", uuid);
3486 } else {
3487 snprintf(sessionid, sizeof(sessionid), "%s", uuid);
3488 switch_core_session_rwunlock(session);
3489 }
3490 }
3491
3492 stream->write_function(stream,
3493 "span_id: %u\n"
3494 "chan_id: %u\n"
3495 "physical_span_id: %u\n"
3496 "physical_chan_id: %u\n"
3497 "physical_status: %s\n"
3498 "signaling_status: %s\n"
3499 "type: %s\n"
3500 "state: %s\n"
3501 "last_state: %s\n"
3502 "txgain: %3.2f\n"
3503 "rxgain: %3.2f\n"
3504 "cid_date: %s\n"
3505 "cid_name: %s\n"
3506 "cid_num: %s\n"
3507 "ani: %s\n"
3508 "aniII: %s\n"
3509 "dnis: %s\n"
3510 "rdnis: %s\n"
3511 "cause: %s\n"
3512 "session: %s\n\n",
3513 span_id,
3514 chan_id,
3515 phspan_id,
3516 phchan_id,
3517 alarmflag ? "alarmed" : "ok",
3518 ftdm_signaling_status2str(sigstatus),
3519 chan_type,
3520 state,
3521 last_state,
3522 txgain,
3523 rxgain,
3524 caller_data->cid_date,
3525 caller_data->cid_name,
3526 caller_data->cid_num.digits,
3527 caller_data->ani.digits,
3528 caller_data->aniII,
3529 caller_data->dnis.digits,
3530 caller_data->rdnis.digits,
3531 switch_channel_cause2str(caller_data->hangup_cause),
3532 sessionid);
3533 }
3534
3535 void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stream)
3536 {
3537 uint32_t span_id;
3538 uint32_t phspan_id, phchan_id;
3539 const char *chan_type;
3540 const char *state;
3541 const char *last_state;
3542 float txgain, rxgain;
3543 ftdm_caller_data_t *caller_data;
3544 ftdm_channel_t *ftdmchan;
3545 ftdm_alarm_flag_t alarmflag;
3546 ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN;
3547
3548 if (chan_id > ftdm_span_get_chan_count(span)) {
3549 return;
3550 }
3551
3552 ftdmchan = ftdm_span_get_channel(span, chan_id);
3553 span_id = ftdm_span_get_id(span);
3554
3555 phspan_id = ftdm_channel_get_ph_span_id(ftdmchan);
3556 phchan_id = ftdm_channel_get_ph_id(ftdmchan);
3557 chan_type = ftdm_chan_type2str(ftdm_channel_get_type(ftdmchan));
3558 state = ftdm_channel_get_state_str(ftdmchan);
3559 last_state = ftdm_channel_get_last_state_str(ftdmchan);
3560 ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_RX_GAIN, &rxgain);
3561 ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_TX_GAIN, &txgain);
3562 caller_data = ftdm_channel_get_caller_data(ftdmchan);
3563 ftdm_channel_get_sig_status(ftdmchan, &sigstatus);
3564 ftdm_channel_get_alarms(ftdmchan, &alarmflag);
3565
3566
3567 stream->write_function(stream,
3568 " <channel>\n"
3569 " <span-id>%u</span-id>\n"
3570 " <chan-id>%u</chan-id>>\n"
3571 " <physical-span-id>%u</physical-span-id>\n"
3572 " <physical-chan-id>%u</physical-chan-id>\n"
3573 " <physical-status>%s</physical-status>\n"
3574 " <signaling-status>%s</signaling-status>\n"
3575 " <type>%s</type>\n"
3576 " <state>%s</state>\n"
3577 " <last-state>%s</last-state>\n"
3578 " <txgain>%3.2f</txgain>\n"
3579 " <rxgain>%3.2f</rxgain>\n"
3580 " <cid-date>%s</cid-date>\n"
3581 " <cid-name>%s</cid-name>\n"
3582 " <cid-num>%s</cid-num>\n"
3583 " <ani>%s</ani>\n"
3584 " <aniII>%s</aniII>\n"
3585 " <dnis>%s</dnis>\n"
3586 " <rdnis>%s</rdnis>\n"
3587 " <cause>%s</cause>\n"
3588 " </channel>\n",
3589 span_id,
3590 chan_id,
3591 phspan_id,
3592 phchan_id,
3593 alarmflag ? "alarmed" : "ok",
3594 ftdm_signaling_status2str(sigstatus),
3595 chan_type,
3596 state,
3597 last_state,
3598 txgain,
3599 rxgain,
3600 caller_data->cid_date,
3601 caller_data->cid_name,
3602 caller_data->cid_num.digits,
3603 caller_data->ani.digits,
3604 caller_data->aniII,
3605 caller_data->dnis.digits,
3606 caller_data->rdnis.digits,
3607 switch_channel_cause2str(caller_data->hangup_cause));
3608 }
3609
3610 #define FT_SYNTAX "list || dump <span_id> [<chan_id>] || q931_pcap <span_id> on|off [pcapfilename without suffix] || gains <txgain> <rxgain> <span_id> [<chan_id>] || dtmf on|off <span_id> [<chan_id>]"
3611 SWITCH_STANDARD_API(ft_function)
3612 {
3613 char *mycmd = NULL, *argv[10] = { 0 };
3614 int argc = 0;
3615 ftdm_iterator_t *chaniter = NULL;
3616 ftdm_iterator_t *curr = NULL;
3617
3618 if (!zstr(cmd) && (mycmd = strdup(cmd))) {
3619 argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
3620 }
3621
3622 if (!argc) {
3623 stream->write_function(stream, "%s", FT_SYNTAX);
3624 goto end;
3625 }
3626
3627 if (!strcasecmp(argv[0], "dump")) {
3628 if (argc < 2) {
3629 stream->write_function(stream, "-ERR Usage: ftdm dump <span_id> [<chan_id>]\n");
3630 goto end;
3631 } else {
3632 uint32_t chan_id = 0;
3633 ftdm_span_t *span;
3634 char *as = NULL;
3635
3636 ftdm_span_find_by_name(argv[1], &span);
3637
3638 if (argc > 2) {
3639 if (argv[3] && !strcasecmp(argv[2], "as")) {
3640 as = argv[3];
3641 } else {
3642 chan_id = atoi(argv[2]);
3643 }
3644 }
3645
3646 if (argv[4] && !strcasecmp(argv[3], "as")) {
3647 as = argv[4];
3648 }
3649
3650 if (!zstr(as) && !strcasecmp(as, "xml")) {
3651 stream->write_function(stream, "<channels>\n");
3652 if (!span) {
3653 stream->write_function(stream, "<error>invalid span</error>\n");
3654 } else {
3655 if (chan_id) {
3656 if(chan_id > ftdm_span_get_chan_count(span)) {
3657 stream->write_function(stream, "<error>invalid channel</error>\n");
3658 } else {
3659 dump_chan_xml(span, chan_id, stream);
3660 }
3661 } else {
3662 chaniter = ftdm_span_get_chan_iterator(span, NULL);
3663 for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
3664 dump_chan_xml(span, ftdm_channel_get_id(ftdm_iterator_current(curr)), stream);
3665 }
3666 ftdm_iterator_free(chaniter);
3667
3668 }
3669 }
3670 stream->write_function(stream, "</channels>\n");
3671 } else {
3672 if (!span) {
3673 stream->write_function(stream, "-ERR invalid span\n");
3674 } else {
3675 if (chan_id) {
3676 if(chan_id > ftdm_span_get_chan_count(span)) {
3677 stream->write_function(stream, "-ERR invalid channel\n");
3678 } else {
3679 char *dbgstr = NULL;
3680 ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id);
3681 dump_chan(span, chan_id, stream);
3682 dbgstr = ftdm_channel_get_history_str(fchan);
3683 stream->write_function(stream, "%s\n", dbgstr);
3684 ftdm_free(dbgstr);
3685 }
3686 } else {
3687 stream->write_function(stream, "+OK\n");
3688 chaniter = ftdm_span_get_chan_iterator(span, NULL);
3689 for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
3690 dump_chan(span, ftdm_channel_get_id(ftdm_iterator_current(curr)), stream);
3691 }
3692 ftdm_iterator_free(chaniter);
3693
3694 }
3695 }
3696 }
3697 }
3698 } else if (!strcasecmp(argv[0], "list")) {
3699 int j;
3700 for (j = 0 ; j < FTDM_MAX_SPANS_INTERFACE; j++) {
3701 if (SPAN_CONFIG[j].span) {
3702 ftdm_channel_t *fchan;
3703 ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE;
3704 const char *flags = "none";
3705 ftdm_signaling_status_t sigstatus;
3706
3707 if (SPAN_CONFIG[j].analog_options & ANALOG_OPTION_3WAY) {
3708 flags = "3way";
3709 } else if (SPAN_CONFIG[j].analog_options & ANALOG_OPTION_CALL_SWAP) {
3710 flags = "call swap";
3711 }
3712 fchan = ftdm_span_get_channel(SPAN_CONFIG[j].span, 1);
3713 if (fchan) {
3714 ftdm_channel_get_alarms(fchan, &alarmbits);
3715 }
3716
3717 if ((FTDM_SUCCESS == ftdm_span_get_sig_status(SPAN_CONFIG[j].span, &sigstatus))) {
3718 stream->write_function(stream,
3719 "+OK\n"
3720 "span: %u (%s)\n"
3721 "type: %s\n"
3722 "physical_status: %s\n"
3723 "signaling_status: %s\n"
3724 "chan_count: %u\n"
3725 "dialplan: %s\n"
3726 "context: %s\n"
3727 "dial_regex: %s\n"
3728 "fail_dial_regex: %s\n"
3729 "hold_music: %s\n"
3730 "analog_options %s\n",
3731 j,
3732 ftdm_span_get_name(SPAN_CONFIG[j].span),
3733 SPAN_CONFIG[j].type,
3734 alarmbits ? "alarmed" : "ok",
3735 ftdm_signaling_status2str(sigstatus),
3736 ftdm_span_get_chan_count(SPAN_CONFIG[j].span),
3737 SPAN_CONFIG[j].dialplan,
3738 SPAN_CONFIG[j].context,
3739 SPAN_CONFIG[j].dial_regex,
3740 SPAN_CONFIG[j].fail_dial_regex,
3741 SPAN_CONFIG[j].hold_music,
3742 flags
3743 );
3744 } else {
3745 stream->write_function(stream,
3746 "+OK\n"
3747 "span: %u (%s)\n"
3748 "type: %s\n"
3749 "physical_status: %s\n"
3750 "chan_count: %u\n"
3751 "dialplan: %s\n"
3752 "context: %s\n"
3753 "dial_regex: %s\n"
3754 "fail_dial_regex: %s\n"
3755 "hold_music: %s\n"
3756 "analog_options %s\n",
3757 j,
3758 ftdm_span_get_name(SPAN_CONFIG[j].span),
3759 SPAN_CONFIG[j].type,
3760 alarmbits ? "alarmed" : "ok",
3761 ftdm_span_get_chan_count(SPAN_CONFIG[j].span),
3762 SPAN_CONFIG[j].dialplan,
3763 SPAN_CONFIG[j].context,
3764 SPAN_CONFIG[j].dial_regex,
3765 SPAN_CONFIG[j].fail_dial_regex,
3766 SPAN_CONFIG[j].hold_music,
3767 flags
3768 );
3769 }
3770 }
3771 }
3772 } else if (!strcasecmp(argv[0], "stop") || !strcasecmp(argv[0], "start")) {
3773 char *span_name = argv[1];
3774 ftdm_span_t *span = NULL;
3775 ftdm_status_t status;
3776
3777 if (span_name) {
3778 ftdm_span_find_by_name(span_name, &span);
3779 }
3780
3781 if (!span) {
3782 stream->write_function(stream, "-ERR no span\n");
3783 goto end;
3784 }
3785
3786 if (!strcasecmp(argv[0], "stop")) {
3787 status = ftdm_span_stop(span);
3788 } else {
3789 status = ftdm_span_start(span);
3790 }
3791
3792 stream->write_function(stream, status == FTDM_SUCCESS ? "+OK\n" : "-ERR failure\n");
3793
3794 goto end;
3795
3796
3797 } else if (!strcasecmp(argv[0], "q931_pcap")) {
3798 int32_t span_id = 0;
3799 ftdm_span_t *span;
3800 const char *pcapfn = NULL;
3801 char *tmp_path = NULL;
3802
3803 if (argc < 3) {
3804 stream->write_function(stream, "-ERR Usage: ftdm q931_pcap <span_id> on|off [pcapfilename without suffix]\n");
3805 goto end;
3806 }
3807 span_id = atoi(argv[1]);
3808 if (!(span_id && (span = SPAN_CONFIG[span_id].span))) {
3809 stream->write_function(stream, "-ERR invalid span\n");
3810 goto end;
3811 }
3812
3813
3814 if (argc > 3) {
3815 if(argv[3]){
3816 pcapfn=argv[3];
3817 }
3818 }
3819 else {
3820 pcapfn="q931";
3821 }
3822
3823
3824 tmp_path=switch_mprintf("%s%s%s.pcap", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, pcapfn);
3825
3826 if(!strcasecmp(argv[2], "on")) {
3827 if (ftdm_configure_span(span, "isdn", on_clear_channel_signal, "q931topcap", 1, "pcapfilename", tmp_path, FTDM_TAG_END) != FTDM_SUCCESS) {
3828 ftdm_log(FTDM_LOG_WARNING, "Error couldn't (re-)enable Q931-To-Pcap!\n");
3829 goto end;
3830 } else {
3831 stream->write_function(stream, "+OK\n");
3832 }
3833 } else if(!strcasecmp(argv[2], "off")) {
3834 if (ftdm_configure_span(span, "isdn", on_clear_channel_signal, "q931topcap", 0, FTDM_TAG_END) != FTDM_SUCCESS) {
3835 ftdm_log(FTDM_LOG_ERROR, "Error couldn't enable Q931-To-Pcap!\n");
3836 goto end;
3837 } else {
3838 stream->write_function(stream, "+OK\n");
3839 }
3840 } else {
3841 stream->write_function(stream, "-ERR Usage: ft q931_pcap <span_id> on|off [pcapfilename without suffix]\n");
3842 goto end;
3843 }
3844
3845 } else if (!strcasecmp(argv[0], "dtmf")) {
3846 unsigned i = 0;
3847 uint32_t chan_id = 0;
3848 unsigned schan_count = 0;
3849 ftdm_span_t *span = NULL;
3850 ftdm_command_t fcmd = FTDM_COMMAND_ENABLE_DTMF_DETECT;
3851 ftdm_channel_t *fchan;
3852 if (argc < 3) {
3853 stream->write_function(stream, "-ERR Usage: dtmf on|off <span_id> [<chan_id>]\n");
3854 goto end;
3855 }
3856
3857 if (switch_true(argv[1])) {
3858 fcmd = FTDM_COMMAND_ENABLE_DTMF_DETECT;
3859 } else {
3860 fcmd = FTDM_COMMAND_DISABLE_DTMF_DETECT;
3861 }
3862
3863 ftdm_span_find_by_name(argv[2], &span);
3864 if (!span) {
3865 stream->write_function(stream, "-ERR invalid span\n");
3866 goto end;
3867 }
3868 schan_count = ftdm_span_get_chan_count(span);
3869 if (argc > 3) {
3870 chan_id = atoi(argv[3]);
3871 if (chan_id > schan_count) {
3872 stream->write_function(stream, "-ERR invalid chan\n");
3873 goto end;
3874 }
3875 }
3876
3877 if (chan_id) {
3878 fchan = ftdm_span_get_channel(span, chan_id);
3879 ftdm_channel_command(fchan, fcmd, NULL);
3880 } else {
3881 for (i = 1; i <= schan_count; i++) {
3882 fchan = ftdm_span_get_channel(span, i);
3883 ftdm_channel_command(fchan, fcmd, NULL);
3884 }
3885 }
3886
3887 stream->write_function(stream, "+OK DTMF detection was %s\n", fcmd == FTDM_COMMAND_ENABLE_DTMF_DETECT ? "enabled" : "disabled");
3888 } else if (!strcasecmp(argv[0], "trace")) {
3889 char tracepath[255];
3890 unsigned i = 0;
3891 uint32_t chan_id = 0;
3892 uint32_t span_id = 0;
3893 uint32_t chan_count = 0;
3894 ftdm_span_t *span = NULL;
3895 ftdm_channel_t *chan = NULL;
3896 if (argc < 3) {
3897 stream->write_function(stream, "-ERR Usage: ftdm trace <path> <span_id> [<chan_id>]\n");
3898 goto end;
3899 }
3900 ftdm_span_find_by_name(argv[2], &span);
3901 if (!span) {
3902 stream->write_function(stream, "-ERR invalid span\n");
3903 goto end;
3904 }
3905 chan_count = ftdm_span_get_chan_count(span);
3906 if (argc > 3) {
3907 chan_id = atoi(argv[3]);
3908 if (chan_id > chan_count) {
3909 stream->write_function(stream, "-ERR invalid chan\n");
3910 goto end;
3911 }
3912 }
3913 span_id = ftdm_span_get_id(span);
3914 if (chan_id) {
3915 chan = ftdm_span_get_channel(span, chan_id);
3916 snprintf(tracepath, sizeof(tracepath), "%s-in-s%dc%d", argv[1], span_id, chan_id);
3917 ftdm_channel_command(chan, FTDM_COMMAND_TRACE_INPUT, tracepath);
3918 snprintf(tracepath, sizeof(tracepath), "%s-out-s%dc%d", argv[1], span_id, chan_id);
3919 ftdm_channel_command(chan, FTDM_COMMAND_TRACE_OUTPUT, tracepath);
3920 } else {
3921 for (i = 1; i <= chan_count; i++) {
3922 chan = ftdm_span_get_channel(span, i);
3923 snprintf(tracepath, sizeof(tracepath), "%s-in-s%dc%d", argv[1], span_id, i);
3924 ftdm_channel_command(chan, FTDM_COMMAND_TRACE_INPUT, tracepath);
3925 snprintf(tracepath, sizeof(tracepath), "%s-out-s%dc%d", argv[1], span_id, i);
3926 ftdm_channel_command(chan, FTDM_COMMAND_TRACE_OUTPUT, tracepath);
3927 }
3928 }
3929 stream->write_function(stream, "+OK trace enabled with prefix path %s\n", argv[1]);
3930 } else if (!strcasecmp(argv[0], "notrace")) {
3931 uint32_t i = 0;
3932 uint32_t chan_id = 0;
3933 uint32_t chan_count = 0;
3934 ftdm_channel_t *fchan = NULL;
3935 ftdm_span_t *span = NULL;
3936 if (argc < 2) {
3937 stream->write_function(stream, "-ERR Usage: ftdm notrace <span_id> [<chan_id>]\n");
3938 goto end;
3939 }
3940 ftdm_span_find_by_name(argv[1], &span);
3941 if (!span) {
3942 stream->write_function(stream, "-ERR invalid span\n");
3943 goto end;
3944 }
3945 chan_count = ftdm_span_get_chan_count(span);
3946 if (argc > 2) {
3947 chan_id = atoi(argv[2]);
3948 if (chan_id > chan_count) {
3949 stream->write_function(stream, "-ERR invalid chan\n");
3950 goto end;
3951 }
3952 }
3953 if (chan_id) {
3954 fchan = ftdm_span_get_channel(span, chan_id);
3955 ftdm_channel_command(fchan, FTDM_COMMAND_TRACE_END_ALL, NULL);
3956 } else {
3957 for (i = 1; i <= chan_count; i++) {
3958 fchan = ftdm_span_get_channel(span, i);
3959 ftdm_channel_command(fchan, FTDM_COMMAND_TRACE_END_ALL, NULL);
3960 }
3961 }
3962 stream->write_function(stream, "+OK trace disabled\n");
3963 } else if (!strcasecmp(argv[0], "gains")) {
3964 unsigned int i = 0;
3965 float txgain = 0.0;
3966 float rxgain = 0.0;
3967 uint32_t chan_id = 0;
3968 uint32_t ccount = 0;
3969 ftdm_channel_t *chan;
3970 ftdm_span_t *span = NULL;
3971 if (argc < 4) {
3972 stream->write_function(stream, "-ERR Usage: ft gains <txgain> <rxgain> <span_id> [<chan_id>]\n");
3973 goto end;
3974 }
3975 ftdm_span_find_by_name(argv[3], &span);
3976 if (!span) {
3977 stream->write_function(stream, "-ERR invalid span\n");
3978 goto end;
3979 }
3980 if (argc > 4) {
3981 chan_id = atoi(argv[4]);
3982 if (chan_id > ftdm_span_get_chan_count(span)) {
3983 stream->write_function(stream, "-ERR invalid chan\n");
3984 goto end;
3985 }
3986 }
3987 i = sscanf(argv[1], "%f", &rxgain);
3988 i += sscanf(argv[2], "%f", &txgain);
3989 if (i != 2) {
3990 stream->write_function(stream, "-ERR invalid gains\n");
3991 goto end;
3992 }
3993
3994 if (chan_id) {
3995 chan = ftdm_span_get_channel(span, chan_id);
3996 ftdm_channel_command(chan, FTDM_COMMAND_SET_RX_GAIN, &rxgain);
3997 ftdm_channel_command(chan, FTDM_COMMAND_SET_TX_GAIN, &txgain);
3998 } else {
3999 ccount = ftdm_span_get_chan_count(span);
4000 for (i = 1; i < ccount; i++) {
4001 chan = ftdm_span_get_channel(span, i);
4002 ftdm_channel_command(chan, FTDM_COMMAND_SET_RX_GAIN, &rxgain);
4003 ftdm_channel_command(chan, FTDM_COMMAND_SET_TX_GAIN, &txgain);
4004 }
4005 }
4006 stream->write_function(stream, "+OK gains set to Rx %f and Tx %f\n", rxgain, txgain);
4007 } else {
4008
4009 char *rply = ftdm_api_execute(cmd);
4010
4011 if (rply) {
4012 stream->write_function(stream, "%s", rply);
4013 ftdm_free(rply);
4014 } else {
4015 stream->write_function(stream, "-ERR Usage: %s\n", FT_SYNTAX);
4016 }
4017 }
4018
4019
4020 end:
4021
4022 switch_safe_free(mycmd);
4023
4024 return SWITCH_STATUS_SUCCESS;
4025 }
4026
4027 SWITCH_STANDARD_APP(enable_dtmf_function)
4028 {
4029 private_t *tech_pvt;
4030 if (!switch_core_session_check_interface(session, freetdm_endpoint_interface)) {
4031 ftdm_log(FTDM_LOG_ERROR, "This application is only for FreeTDM channels.\n");
4032 return;
4033 }
4034
4035 tech_pvt = switch_core_session_get_private(session);
4036
4037 if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
4038 switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE);
4039 return;
4040 }
4041
4042 ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, NULL);
4043 ftdm_log(FTDM_LOG_INFO, "DTMF detection enabled in channel %d:%d\n", ftdm_channel_get_id(tech_pvt->ftdmchan), ftdm_channel_get_span_id(tech_pvt->ftdmchan));
4044 }
4045
4046 SWITCH_STANDARD_APP(disable_dtmf_function)
4047 {
4048 private_t *tech_pvt;
4049 if (!switch_core_session_check_interface(session, freetdm_endpoint_interface)) {
4050 ftdm_log(FTDM_LOG_ERROR, "This application is only for FreeTDM channels.\n");
4051 return;
4052 }
4053
4054 tech_pvt = switch_core_session_get_private(session);
4055
4056 if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
4057 switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE);
4058 return;
4059 }
4060
4061 ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_DTMF_DETECT, NULL);
4062 ftdm_log(FTDM_LOG_INFO, "DTMF detection Disabled in channel %d:%d\n", ftdm_channel_get_id(tech_pvt->ftdmchan), ftdm_channel_get_span_id(tech_pvt->ftdmchan));
4063 }
4064
4065 SWITCH_STANDARD_APP(disable_ec_function)
4066 {
4067 private_t *tech_pvt;
4068 int x = 0;
4069
4070 if (!switch_core_session_check_interface(session, freetdm_endpoint_interface)) {
4071 ftdm_log(FTDM_LOG_ERROR, "This application is only for FreeTDM channels.\n");
4072 return;
4073 }
4074
4075 tech_pvt = switch_core_session_get_private(session);
4076
4077 if (switch_test_flag(tech_pvt, TFLAG_DEAD)) {
4078 switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_LOSE_RACE);
4079 return;
4080 }
4081
4082 ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_ECHOCANCEL, &x);
4083 ftdm_channel_command(tech_pvt->ftdmchan, FTDM_COMMAND_DISABLE_ECHOTRAIN, &x);
4084 ftdm_log(FTDM_LOG_INFO, "Echo Canceller Disabled\n");
4085 }
4086
4087
4088 SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load)
4089 {
4090
4091 switch_api_interface_t *commands_api_interface;
4092 switch_application_interface_t *app_interface;
4093
4094 module_pool = pool;
4095
4096 ftdm_global_set_logger(ftdm_logger);
4097
4098 ftdm_global_set_mod_directory(SWITCH_GLOBAL_dirs.mod_dir);
4099
4100 ftdm_global_set_config_directory(SWITCH_GLOBAL_dirs.conf_dir);
4101
4102 if (ftdm_global_init() != FTDM_SUCCESS) {
4103 ftdm_log(FTDM_LOG_ERROR, "Error loading FreeTDM\n");
4104 return SWITCH_STATUS_TERM;
4105 }
4106
4107 if (ftdm_global_configuration() != FTDM_SUCCESS) {
4108 ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM\n");
4109 return SWITCH_STATUS_TERM;
4110 }
4111
4112 if (load_config() != SWITCH_STATUS_SUCCESS) {
4113 ftdm_global_destroy();
4114 return SWITCH_STATUS_TERM;
4115 }
4116
4117 *module_interface = switch_loadable_module_create_module_interface(pool, modname);
4118 freetdm_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
4119 freetdm_endpoint_interface->interface_name = "freetdm";
4120 freetdm_endpoint_interface->io_routines = &freetdm_io_routines;
4121 freetdm_endpoint_interface->state_handler = &freetdm_state_handlers;
4122
4123 SWITCH_ADD_API(commands_api_interface, "ftdm", "FreeTDM commands", ft_function, FT_SYNTAX);
4124
4125 SWITCH_ADD_APP(app_interface, "disable_ec", "Disable Echo Canceller", "Disable Echo Canceller", disable_ec_function, "", SAF_NONE);
4126 SWITCH_ADD_APP(app_interface, "disable_dtmf", "Disable DTMF Detection", "Disable DTMF Detection", disable_dtmf_function, "", SAF_NONE);
4127 SWITCH_ADD_APP(app_interface, "enable_dtmf", "Enable DTMF Detection", "Enable DTMF Detection", enable_dtmf_function, "", SAF_NONE);
4128
4129
4130 return SWITCH_STATUS_SUCCESS;
4131 }
4132
4133 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_freetdm_shutdown)
4134 {
4135 switch_hash_index_t *hi;
4136
4137 const void *var;
4138 void *val;
4139
4140
4141 for (hi = switch_hash_first(NULL, globals.ss7_configs); hi; hi = switch_hash_next(hi)) {
4142 switch_hash_this(hi, &var, NULL, &val);
4143 ftdm_conf_node_destroy(val);
4144 }
4145
4146 ftdm_global_destroy();
4147
4148
4149
4150 return SWITCH_STATUS_SUCCESS;
4151 }
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162