This source file includes following definitions.
- FIO_CHANNEL_OUTGOING_CALL_FUNCTION
- ftdm_analog_em_start
- FIO_CHANNEL_GET_SIG_STATUS_FUNCTION
- FIO_SPAN_GET_SIG_STATUS_FUNCTION
- FIO_SIG_CONFIGURE_FUNCTION
- teletone_handler
- ftdm_analog_em_channel_run
- process_event
- ftdm_analog_em_run
- FIO_SIG_LOAD_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
35
36
37
38
39 #include "private/ftdm_core.h"
40 #include "ftdm_analog_em.h"
41
42 #ifndef localtime_r
43 struct tm * localtime_r(const time_t *clock, struct tm *result);
44 #endif
45
46 static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj);
47
48
49
50
51
52
53
54
55 static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_em_outgoing_call)
56 {
57 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) {
58 ftdm_channel_clear_needed_tones(ftdmchan);
59 ftdm_channel_clear_detected_tones(ftdmchan);
60
61 ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
62
63 ftdm_channel_command(ftdmchan, FTDM_COMMAND_OFFHOOK, NULL);
64 ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_PROGRESS_DETECT, NULL);
65 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DIALING);
66 ftdm_thread_create_detached(ftdm_analog_em_channel_run, ftdmchan);
67 return FTDM_SUCCESS;
68 }
69
70 return FTDM_FAIL;
71 }
72
73
74
75
76
77
78 static ftdm_status_t ftdm_analog_em_start(ftdm_span_t *span)
79 {
80 ftdm_analog_em_data_t *analog_data = span->signal_data;
81 ftdm_set_flag(analog_data, FTDM_ANALOG_EM_RUNNING);
82 return ftdm_thread_create_detached(ftdm_analog_em_run, span);
83 }
84
85
86
87
88
89
90
91
92 static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(analog_em_get_channel_sig_status)
93 {
94 *status = FTDM_SIG_STATE_UP;
95 return FTDM_SUCCESS;
96 }
97
98
99
100
101
102
103
104
105 static FIO_SPAN_GET_SIG_STATUS_FUNCTION(analog_em_get_span_sig_status)
106 {
107 *status = FTDM_SIG_STATE_UP;
108 return FTDM_SUCCESS;
109 }
110
111
112
113
114
115
116
117
118 static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_em_configure_span)
119
120 {
121 ftdm_analog_em_data_t *analog_data;
122 const char *tonemap = "us";
123 uint32_t digit_timeout = 10;
124 uint32_t max_dialstr = 11;
125 const char *var, *val;
126 int *intval;
127
128 assert(sig_cb != NULL);
129
130 if (span->signal_type) {
131 snprintf(span->last_error, sizeof(span->last_error), "Span is already configured for signalling.");
132 return FTDM_FAIL;
133 }
134
135 analog_data = ftdm_malloc(sizeof(*analog_data));
136 assert(analog_data != NULL);
137 memset(analog_data, 0, sizeof(*analog_data));
138
139 while((var = va_arg(ap, char *))) {
140 if (!strcasecmp(var, "tonemap")) {
141 if (!(val = va_arg(ap, char *))) {
142 break;
143 }
144 tonemap = val;
145 } else if (!strcasecmp(var, "digit_timeout")) {
146 if (!(intval = va_arg(ap, int *))) {
147 break;
148 }
149 digit_timeout = *intval;
150 } else if (!strcasecmp(var, "max_dialstr")) {
151 if (!(intval = va_arg(ap, int *))) {
152 break;
153 }
154 max_dialstr = *intval;
155 } else {
156 snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var);
157 return FTDM_FAIL;
158 }
159 }
160
161
162 if (digit_timeout < 2000 || digit_timeout > 10000) {
163 digit_timeout = 2000;
164 }
165
166 if (max_dialstr < 2 || max_dialstr > MAX_DIALSTRING) {
167 ftdm_log(FTDM_LOG_ERROR, "Invalid max_dialstr, setting to %d\n", MAX_DIALSTRING);
168 max_dialstr = MAX_DIALSTRING;
169 }
170
171 span->start = ftdm_analog_em_start;
172 analog_data->digit_timeout = digit_timeout;
173 analog_data->max_dialstr = max_dialstr;
174 span->signal_cb = sig_cb;
175 span->signal_type = FTDM_SIGTYPE_ANALOG;
176 span->signal_data = analog_data;
177 span->outgoing_call = analog_em_outgoing_call;
178 span->get_channel_sig_status = analog_em_get_channel_sig_status;
179 span->get_span_sig_status = analog_em_get_span_sig_status;
180 ftdm_span_load_tones(span, tonemap);
181
182 return FTDM_SUCCESS;
183
184 }
185
186
187
188
189
190
191
192 static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
193 {
194 ftdm_buffer_t *dt_buffer = ts->user_data;
195 int wrote;
196
197 if (!dt_buffer) {
198 return -1;
199 }
200 wrote = teletone_mux_tones(ts, map);
201 ftdm_buffer_write(dt_buffer, ts->buffer, wrote * 2);
202 return 0;
203 }
204
205
206
207
208
209
210 static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
211 {
212 ftdm_channel_t *ftdmchan = (ftdm_channel_t *) obj;
213 ftdm_buffer_t *dt_buffer = NULL;
214 teletone_generation_session_t ts;
215 uint8_t frame[1024];
216 ftdm_size_t len, rlen;
217 ftdm_tone_type_t tt = FTDM_TONE_DTMF;
218 char dtmf[128] = "";
219 ftdm_size_t dtmf_offset = 0;
220 ftdm_analog_em_data_t *analog_data = ftdmchan->span->signal_data;
221 ftdm_channel_t *closed_chan;
222 uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = 30000;
223 ftdm_sigmsg_t sig;
224 ftdm_status_t status;
225
226 ftdm_log(FTDM_LOG_DEBUG, "ANALOG EM CHANNEL thread starting.\n");
227
228 ts.buffer = NULL;
229
230 if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
231 ftdm_log(FTDM_LOG_ERROR, "OPEN ERROR [%s]\n", ftdmchan->last_error);
232 goto done;
233 }
234
235 if (ftdm_buffer_create(&dt_buffer, 1024, 3192, 0) != FTDM_SUCCESS) {
236 snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "memory error!");
237 ftdm_log(FTDM_LOG_ERROR, "MEM ERROR\n");
238 goto done;
239 }
240
241 if (ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_DTMF_DETECT, &tt) != FTDM_SUCCESS) {
242 snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "error initilizing tone detector!");
243 ftdm_log(FTDM_LOG_ERROR, "TONE ERROR\n");
244 goto done;
245 }
246
247 ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_INTHREAD);
248 teletone_init_session(&ts, 0, teletone_handler, dt_buffer);
249 ts.rate = 8000;
250 #if 0
251 ts.debug = 1;
252 ts.debug_stream = stdout;
253 #endif
254 ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_INTERVAL, &interval);
255 ftdm_buffer_set_loops(dt_buffer, -1);
256
257 memset(&sig, 0, sizeof(sig));
258 sig.chan_id = ftdmchan->chan_id;
259 sig.span_id = ftdmchan->span_id;
260 sig.channel = ftdmchan;
261
262 assert(interval != 0);
263
264 while (ftdm_running() && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INTHREAD)) {
265 ftdm_wait_flag_t flags = FTDM_READ;
266 ftdm_size_t dlen = 0;
267
268 len = sizeof(frame);
269
270 elapsed += interval;
271 state_counter += interval;
272
273 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
274 switch(ftdmchan->state) {
275 case FTDM_CHANNEL_STATE_DIALING:
276 {
277 if (! ftdmchan->needed_tones[FTDM_TONEMAP_RING]
278 && ftdm_test_flag(ftdmchan, FTDM_CHANNEL_WINK)) {
279 if (ftdm_strlen_zero(ftdmchan->caller_data.dnis.digits)) {
280 ftdm_log(FTDM_LOG_ERROR, "No Digits to send!\n");
281 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
282 } else {
283 if (ftdm_channel_command(ftdmchan, FTDM_COMMAND_SEND_DTMF, ftdmchan->caller_data.dnis.digits) != FTDM_SUCCESS) {
284 ftdm_log(FTDM_LOG_ERROR, "Send Digits Failed [%s]\n", ftdmchan->last_error);
285 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
286 } else {
287 state_counter = 0;
288 ftdmchan->needed_tones[FTDM_TONEMAP_RING] = 1;
289 ftdmchan->needed_tones[FTDM_TONEMAP_BUSY] = 1;
290 ftdmchan->needed_tones[FTDM_TONEMAP_FAIL1] = 1;
291 ftdmchan->needed_tones[FTDM_TONEMAP_FAIL2] = 1;
292 ftdmchan->needed_tones[FTDM_TONEMAP_FAIL3] = 1;
293 dial_timeout = ((ftdmchan->dtmf_on + ftdmchan->dtmf_off) * strlen(ftdmchan->caller_data.dnis.digits)) + 2000;
294 }
295 }
296 break;
297 }
298 if (state_counter > dial_timeout) {
299 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_WINK)) {
300 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
301 } else {
302 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
303 }
304 }
305 }
306 break;
307 case FTDM_CHANNEL_STATE_DIALTONE:
308 {
309 if (state_counter > 10000) {
310 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
311 }
312 }
313 break;
314 case FTDM_CHANNEL_STATE_BUSY:
315 {
316 if (state_counter > 20000) {
317 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_ATTN);
318 }
319 }
320 break;
321 case FTDM_CHANNEL_STATE_ATTN:
322 {
323 if (state_counter > 20000) {
324 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
325 }
326 }
327 break;
328 case FTDM_CHANNEL_STATE_HANGUP:
329 {
330 if (state_counter > 500) {
331 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) &&
332 (ftdmchan->last_state == FTDM_CHANNEL_STATE_RING || ftdmchan->last_state == FTDM_CHANNEL_STATE_DIALTONE
333 || ftdmchan->last_state >= FTDM_CHANNEL_STATE_IDLE)) {
334 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
335 } else {
336 ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
337 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
338 }
339 }
340 }
341 break;
342 case FTDM_CHANNEL_STATE_UP:
343 case FTDM_CHANNEL_STATE_IDLE:
344 {
345 ftdm_sleep(interval);
346 continue;
347 }
348 break;
349 case FTDM_CHANNEL_STATE_DOWN:
350 {
351 goto done;
352 }
353 break;
354 default:
355 break;
356 }
357 } else {
358 ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
359 ftdm_clear_flag_locked(ftdmchan->span, FTDM_SPAN_STATE_CHANGE);
360 ftdm_channel_complete_state(ftdmchan);
361 indicate = 0;
362 state_counter = 0;
363
364 ftdm_log(FTDM_LOG_DEBUG, "Executing state handler on %d:%d for %s\n",
365 ftdmchan->span_id, ftdmchan->chan_id,
366 ftdm_channel_state2str(ftdmchan->state));
367 switch(ftdmchan->state) {
368 case FTDM_CHANNEL_STATE_UP:
369 {
370 ftdm_channel_use(ftdmchan);
371 ftdm_channel_clear_needed_tones(ftdmchan);
372 ftdm_channel_flush_dtmf(ftdmchan);
373
374 if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK)) {
375 ftdm_channel_command(ftdmchan, FTDM_COMMAND_OFFHOOK, NULL);
376 }
377
378 sig.event_id = FTDM_SIGEVENT_UP;
379
380 ftdm_span_send_signal(ftdmchan->span, &sig);
381 continue;
382 }
383 break;
384 case FTDM_CHANNEL_STATE_DIALING:
385 {
386 ftdm_channel_use(ftdmchan);
387 }
388 break;
389 case FTDM_CHANNEL_STATE_IDLE:
390 {
391 ftdm_channel_use(ftdmchan);
392
393 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
394 ftdm_set_string(ftdmchan->caller_data.dnis.digits, ftdmchan->chan_number);
395 } else {
396 ftdm_set_string(ftdmchan->caller_data.dnis.digits, dtmf);
397 }
398
399 sig.event_id = FTDM_SIGEVENT_START;
400
401 ftdm_span_send_signal(ftdmchan->span, &sig);
402 continue;
403 }
404 break;
405 case FTDM_CHANNEL_STATE_DOWN:
406 {
407 sig.event_id = FTDM_SIGEVENT_STOP;
408 ftdm_span_send_signal(ftdmchan->span, &sig);
409 goto done;
410 }
411 break;
412 case FTDM_CHANNEL_STATE_DIALTONE:
413 {
414 memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
415 *dtmf = '\0';
416 dtmf_offset = 0;
417 ftdm_buffer_zero(dt_buffer);
418 teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_DIAL]);
419 indicate = 1;
420
421 ftdm_channel_command(ftdmchan, FTDM_COMMAND_WINK, NULL);
422 }
423 break;
424 case FTDM_CHANNEL_STATE_RING:
425 {
426 ftdm_buffer_zero(dt_buffer);
427 teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_RING]);
428 indicate = 1;
429 }
430 break;
431 case FTDM_CHANNEL_STATE_BUSY:
432 {
433 ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CIRCUIT_CONGESTION;
434 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
435 ftdm_buffer_zero(dt_buffer);
436 teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_BUSY]);
437 indicate = 1;
438 } else {
439 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
440 }
441 }
442 break;
443 case FTDM_CHANNEL_STATE_ATTN:
444 {
445 if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OFFHOOK) && !ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
446 ftdm_buffer_zero(dt_buffer);
447 teletone_run(&ts, ftdmchan->span->tone_map[FTDM_TONEMAP_ATTN]);
448 indicate = 1;
449 } else {
450 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
451 }
452 }
453 break;
454 default:
455 break;
456 }
457 }
458
459
460 if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALTONE || ftdmchan->state == FTDM_CHANNEL_STATE_COLLECT) {
461 if ((dlen = ftdm_channel_dequeue_dtmf(ftdmchan, dtmf + dtmf_offset, sizeof(dtmf) - strlen(dtmf)))) {
462
463 if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALTONE) {
464 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
465 collecting = 1;
466 }
467 dtmf_offset = strlen(dtmf);
468 last_digit = elapsed;
469 sig.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT;
470 sig.raw_data = dtmf;
471 if (ftdm_span_send_signal(ftdmchan->span, &sig) == FTDM_BREAK) {
472 collecting = 0;
473 }
474 }
475 }
476
477
478 if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) > analog_data->max_dialstr))) {
479 ftdm_log(FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf);
480 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
481 last_digit = 0;
482 collecting = 0;
483 }
484
485 if (ftdm_channel_wait(ftdmchan, &flags, interval * 2) != FTDM_SUCCESS) {
486 continue;
487 }
488
489 if (!(flags & FTDM_READ)) {
490 continue;
491 }
492
493 if (ftdm_channel_read(ftdmchan, frame, &len) != FTDM_SUCCESS) {
494 ftdm_log(FTDM_LOG_ERROR, "READ ERROR [%s]\n", ftdmchan->last_error);
495 goto done;
496 }
497
498 if (ftdmchan->detected_tones[0]) {
499 int i;
500
501 for (i = 1; i < FTDM_TONEMAP_INVALID; i++) {
502 if (ftdmchan->detected_tones[i]) {
503 ftdm_log(FTDM_LOG_DEBUG, "Detected tone %s on %d:%d\n", ftdm_tonemap2str(i), ftdmchan->span_id, ftdmchan->chan_id);
504 }
505 }
506
507 if (ftdmchan->detected_tones[FTDM_TONEMAP_BUSY] ||
508 ftdmchan->detected_tones[FTDM_TONEMAP_FAIL1] ||
509 ftdmchan->detected_tones[FTDM_TONEMAP_FAIL2] ||
510 ftdmchan->detected_tones[FTDM_TONEMAP_FAIL3] ||
511 ftdmchan->detected_tones[FTDM_TONEMAP_ATTN]
512 ) {
513 ftdm_log(FTDM_LOG_ERROR, "Failure indication detected!\n");
514 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_BUSY);
515 } else if (ftdmchan->detected_tones[FTDM_TONEMAP_RING]) {
516 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
517 }
518
519 ftdm_channel_clear_detected_tones(ftdmchan);
520 }
521
522 if ((ftdmchan->dtmf_buffer && ftdm_buffer_inuse(ftdmchan->dtmf_buffer))) {
523 rlen = len;
524 memset(frame, 0, len);
525 ftdm_channel_write(ftdmchan, frame, sizeof(frame), &rlen);
526 continue;
527 }
528
529 if (!indicate) {
530 continue;
531 }
532
533 if (ftdmchan->effective_codec != FTDM_CODEC_SLIN) {
534 len *= 2;
535 }
536
537 rlen = ftdm_buffer_read_loop(dt_buffer, frame, len);
538
539 if (ftdmchan->effective_codec != FTDM_CODEC_SLIN) {
540 fio_codec_t codec_func = NULL;
541
542 if (ftdmchan->native_codec == FTDM_CODEC_ULAW) {
543 codec_func = fio_slin2ulaw;
544 } else if (ftdmchan->native_codec == FTDM_CODEC_ALAW) {
545 codec_func = fio_slin2alaw;
546 }
547
548 if (codec_func) {
549 status = codec_func(frame, sizeof(frame), &rlen);
550 } else {
551 snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!");
552 goto done;
553 }
554 }
555
556 ftdm_channel_write(ftdmchan, frame, sizeof(frame), &rlen);
557 }
558
559 done:
560
561 ftdm_channel_command(ftdmchan, FTDM_COMMAND_ONHOOK, NULL);
562
563 closed_chan = ftdmchan;
564 ftdm_channel_close(&ftdmchan);
565
566 ftdm_channel_command(closed_chan, FTDM_COMMAND_SET_NATIVE_CODEC, NULL);
567
568 if (ts.buffer) {
569 teletone_destroy_session(&ts);
570 }
571
572 if (dt_buffer) {
573 ftdm_buffer_destroy(&dt_buffer);
574 }
575
576 ftdm_clear_flag(closed_chan, FTDM_CHANNEL_INTHREAD);
577
578 ftdm_log(FTDM_LOG_DEBUG, "ANALOG EM CHANNEL thread ended.\n");
579
580 return NULL;
581 }
582
583
584
585
586
587
588
589 static __inline__ ftdm_status_t process_event(ftdm_span_t *span, ftdm_event_t *event)
590 {
591 ftdm_sigmsg_t sig;
592 int locked = 0;
593
594 memset(&sig, 0, sizeof(sig));
595 sig.chan_id = event->channel->chan_id;
596 sig.span_id = event->channel->span_id;
597 sig.channel = event->channel;
598
599
600 ftdm_log(FTDM_LOG_DEBUG, "EVENT [%s][%d:%d] STATE [%s]\n",
601 ftdm_oob_event2str(event->enum_id), event->channel->span_id, event->channel->chan_id, ftdm_channel_state2str(event->channel->state));
602
603 ftdm_mutex_lock(event->channel->mutex);
604 locked++;
605
606 switch(event->enum_id) {
607 case FTDM_OOB_ONHOOK:
608 {
609 if (event->channel->state != FTDM_CHANNEL_STATE_DOWN) {
610 ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN);
611 }
612
613 }
614 break;
615 case FTDM_OOB_OFFHOOK:
616 {
617 if (ftdm_test_flag(event->channel, FTDM_CHANNEL_INTHREAD)) {
618 ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_UP);
619 } else {
620 ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DIALTONE);
621 ftdm_mutex_unlock(event->channel->mutex);
622 locked = 0;
623 ftdm_thread_create_detached(ftdm_analog_em_channel_run, event->channel);
624 }
625 break;
626 }
627 case FTDM_OOB_WINK:
628 {
629 if (event->channel->state != FTDM_CHANNEL_STATE_DIALING) {
630 ftdm_set_state_locked(event->channel, FTDM_CHANNEL_STATE_DOWN);
631 } else {
632 ftdm_set_flag_locked(event->channel, FTDM_CHANNEL_WINK);
633 }
634
635 }
636 break;
637 }
638 if (locked) {
639 ftdm_mutex_unlock(event->channel->mutex);
640 }
641 return FTDM_SUCCESS;
642 }
643
644
645
646
647
648
649 static void *ftdm_analog_em_run(ftdm_thread_t *me, void *obj)
650 {
651 ftdm_span_t *span = (ftdm_span_t *) obj;
652 ftdm_analog_em_data_t *analog_data = span->signal_data;
653
654 ftdm_log(FTDM_LOG_DEBUG, "ANALOG EM thread starting.\n");
655
656 while(ftdm_running() && ftdm_test_flag(analog_data, FTDM_ANALOG_EM_RUNNING)) {
657 int waitms = 10;
658 ftdm_status_t status;
659
660 status = ftdm_span_poll_event(span, waitms);
661
662 switch(status) {
663 case FTDM_SUCCESS:
664 {
665 ftdm_event_t *event;
666 while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) {
667 if (event->enum_id == FTDM_OOB_NOOP) {
668 continue;
669 }
670 if (process_event(span, event) != FTDM_SUCCESS) {
671 goto end;
672 }
673 }
674 }
675 break;
676 case FTDM_FAIL:
677 {
678 ftdm_log(FTDM_LOG_ERROR, "Failure Polling event! [%s]\n", span->last_error);
679 }
680 break;
681 default:
682 break;
683 }
684
685 }
686
687 end:
688
689 ftdm_clear_flag(analog_data, FTDM_ANALOG_EM_RUNNING);
690
691 ftdm_log(FTDM_LOG_DEBUG, "ANALOG EM thread ending.\n");
692
693 return NULL;
694 }
695
696
697
698
699
700 static FIO_SIG_LOAD_FUNCTION(ftdm_analog_em_init)
701 {
702 return FTDM_SUCCESS;
703 }
704
705
706
707
708 EX_DECLARE_DATA ftdm_module_t ftdm_module = {
709 "analog_em",
710 NULL,
711 NULL,
712 ftdm_analog_em_init,
713 ftdm_analog_em_configure_span,
714 NULL
715 };
716
717
718
719
720
721
722
723
724
725
726
727