Merge a large set of updates to the Asterisk indications API.
[asterisk/asterisk.git] / channels / chan_misdn.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  * 
4  * Copyright (C) 2004 - 2006, Christian Richter
5  *
6  * Christian Richter <crich@beronet.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  *
18  */
19
20 /*!
21  * \file
22  *
23  * \brief the chan_misdn channel driver for Asterisk
24  *
25  * \author Christian Richter <crich@beronet.com>
26  *
27  * \extref MISDN http://www.misdn.org/
28  *
29  * \ingroup channel_drivers
30  */
31
32 /*** MODULEINFO
33         <depend>isdnnet</depend>
34         <depend>misdn</depend>
35         <depend>suppserv</depend>
36  ***/
37 #include "asterisk.h"
38
39 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
40
41 #include <pthread.h>
42 #include <sys/socket.h>
43 #include <sys/time.h>
44 #include <arpa/inet.h>
45 #include <fcntl.h>
46 #include <sys/ioctl.h>
47 #include <signal.h>
48 #include <sys/file.h>
49 #include <semaphore.h>
50
51 #include "asterisk/channel.h"
52 #include "asterisk/config.h"
53 #include "asterisk/module.h"
54 #include "asterisk/pbx.h"
55 #include "asterisk/io.h"
56 #include "asterisk/frame.h"
57 #include "asterisk/translate.h"
58 #include "asterisk/cli.h"
59 #include "asterisk/musiconhold.h"
60 #include "asterisk/dsp.h"
61 #include "asterisk/file.h"
62 #include "asterisk/callerid.h"
63 #include "asterisk/indications.h"
64 #include "asterisk/app.h"
65 #include "asterisk/features.h"
66 #include "asterisk/term.h"
67 #include "asterisk/sched.h"
68 #include "asterisk/stringfields.h"
69 #include "asterisk/abstract_jb.h"
70 #include "asterisk/causes.h"
71
72 #include "chan_misdn_config.h"
73 #include "isdn_lib.h"
74
75 char global_tracefile[BUFFERSIZE + 1];
76
77 static int g_config_initialized = 0;
78
79 struct misdn_jb{
80         int size;
81         int upper_threshold;
82         char *samples, *ok;
83         int wp,rp;
84         int state_empty;
85         int state_full;
86         int state_buffer;
87         int bytes_wrote;
88         ast_mutex_t mutexjb;
89 };
90
91
92
93 /*! \brief allocates the jb-structure and initialize the elements */
94 struct misdn_jb *misdn_jb_init(int size, int upper_threshold);
95
96 /*! \brief frees the data and destroys the given jitterbuffer struct */
97 void misdn_jb_destroy(struct misdn_jb *jb);
98
99 /*! \brief fills the jitterbuffer with len data returns < 0 if there was an
100 error (buffer overrun). */
101 int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len);
102
103 /*! \brief gets len bytes out of the jitterbuffer if available, else only the
104 available data is returned and the return value indicates the number
105 of data. */
106 int misdn_jb_empty(struct misdn_jb *jb, char *data, int len);
107
108 static char *complete_ch(struct ast_cli_args *a);
109 static char *complete_debug_port(struct ast_cli_args *a);
110 static char *complete_show_config(struct ast_cli_args *a);
111
112 /* BEGIN: chan_misdn.h */
113
114 ast_mutex_t release_lock;
115
116 enum misdn_chan_state {
117         MISDN_NOTHING = 0,         /*!< at beginning */
118         MISDN_WAITING4DIGS,        /*!< when waiting for info */
119         MISDN_EXTCANTMATCH,        /*!< when asterisk couldn't match our ext */
120         MISDN_INCOMING_SETUP,      /*!< for incoming setup */
121         MISDN_DIALING,             /*!< when pbx_start */
122         MISDN_PROGRESS,            /*!< we have progress */
123         MISDN_PROCEEDING,          /*!< we have progress */
124         MISDN_CALLING,             /*!< when misdn_call is called */
125         MISDN_CALLING_ACKNOWLEDGE, /*!< when we get SETUP_ACK */
126         MISDN_ALERTING,            /*!< when Alerting */
127         MISDN_BUSY,                /*!< when BUSY */
128         MISDN_CONNECTED,           /*!< when connected */
129         MISDN_PRECONNECTED,        /*!< when connected */
130         MISDN_DISCONNECTED,        /*!< when connected */
131         MISDN_RELEASED,            /*!< when connected */
132         MISDN_BRIDGED,             /*!< when bridged */
133         MISDN_CLEANING,            /*!< when hangup from * but we were connected before */
134         MISDN_HUNGUP_FROM_MISDN,   /*!< when DISCONNECT/RELEASE/REL_COMP came from misdn */
135         MISDN_HUNGUP_FROM_AST,     /*!< when DISCONNECT/RELEASE/REL_COMP came out of misdn_hangup */
136         MISDN_HOLDED,              /*!< when on hold */
137         MISDN_HOLD_DISCONNECT,     /*!< when on hold */
138   
139 };
140
141 #define ORG_AST 1
142 #define ORG_MISDN 2
143
144 struct hold_info {
145         /*!
146          * \brief Logical port the channel call record is HOLDED on 
147          * because the B channel is no longer associated. 
148          */
149         int port;
150
151         /*!
152          * \brief Original B channel number the HOLDED call was using. 
153          * \note Used only for debug display messages.
154          */
155         int channel;
156 };
157
158 /*!
159  * \brief Channel call record structure
160  */
161 struct chan_list {
162         /*! 
163          * \brief The "allowed_bearers" string read in from /etc/asterisk/misdn.conf
164          */
165         char allowed_bearers[BUFFERSIZE + 1];
166         
167         /*! 
168          * \brief State of the channel
169          */
170         enum misdn_chan_state state;
171
172         /*! 
173          * \brief TRUE if a hangup needs to be queued 
174          * \note This is a debug flag only used to catch calls to hangup_chan() that are already hungup.
175          */
176         int need_queue_hangup;
177
178         /*!
179          * \brief TRUE if a channel can be hung up by calling asterisk directly when done.
180          */
181         int need_hangup;
182
183         /*!
184          * \brief TRUE if we could send an AST_CONTROL_BUSY if needed.
185          */
186         int need_busy;
187         
188         /*!
189          * \brief Who originally created this channel. ORG_AST or ORG_MISDN
190          */
191         int originator;
192
193         /*! 
194          * \brief TRUE of we are not to respond immediately to a SETUP message.  Check the dialplan first.
195          * \note The "noautorespond_on_setup" boolean read in from /etc/asterisk/misdn.conf
196          */
197         int noautorespond_on_setup;
198         
199         int norxtone;   /*!< Boolean assigned values but the value is not used. */
200
201         /*!
202          * \brief TRUE if we are not to generate tones (Playtones)
203          */
204         int notxtone; 
205
206         /*!
207          * \brief TRUE if echo canceller is enabled.  Value is toggled.
208          */
209         int toggle_ec;
210         
211         /*!
212          * \brief TRUE if you want to send Tone Indications to an incoming
213          * ISDN channel on a TE Port.
214          * \note The "incoming_early_audio" boolean read in from /etc/asterisk/misdn.conf
215          */
216         int incoming_early_audio;
217
218         /*!
219          * \brief TRUE if DTMF digits are to be passed inband only.
220          * \note It is settable by the misdn_set_opt() application.
221          */
222         int ignore_dtmf;
223
224         /*!
225          * \brief Pipe file descriptor handles array. 
226          * Read from pipe[0], write to pipe[1] 
227          */
228         int pipe[2];
229
230         /*!
231          * \brief Read buffer for inbound audio from pipe[0]
232          */
233         char ast_rd_buf[4096];
234
235         /*!
236          * \brief Inbound audio frame returned by misdn_read().
237          */
238         struct ast_frame frame;
239
240         /*!
241          * \brief Fax detection option. (0:no 1:yes 2:yes+nojump)
242          * \note The "faxdetect" option string read in from /etc/asterisk/misdn.conf
243          * \note It is settable by the misdn_set_opt() application.
244          */
245         int faxdetect;
246
247         /*!
248          * \brief Number of seconds to detect a Fax machine when detection enabled.
249          * \note 0 disables the timeout.
250          * \note The "faxdetect_timeout" value read in from /etc/asterisk/misdn.conf
251          */
252         int faxdetect_timeout;
253
254         /*!
255          * \brief Starting time of fax detection with timeout when nonzero.
256          */
257         struct timeval faxdetect_tv;
258
259         /*!
260          * \brief TRUE if a fax has been detected.
261          */
262         int faxhandled;
263
264         /*!
265          * \brief TRUE if we will use the Asterisk DSP to detect DTMF/Fax
266          * \note The "astdtmf" boolean read in from /etc/asterisk/misdn.conf
267          */
268         int ast_dsp;
269
270         /*!
271          * \brief Jitterbuffer length
272          * \note The "jitterbuffer" value read in from /etc/asterisk/misdn.conf
273          */
274         int jb_len;
275
276         /*!
277          * \brief Jitterbuffer upper threshold
278          * \note The "jitterbuffer_upper_threshold" value read in from /etc/asterisk/misdn.conf
279          */
280         int jb_upper_threshold;
281
282         /*!
283          * \brief Allocated jitterbuffer controller
284          * \note misdn_jb_init() creates the jitterbuffer.
285          * \note Must use misdn_jb_destroy() to clean up. 
286          */
287         struct misdn_jb *jb;
288         
289         /*!
290          * \brief Allocated DSP controller
291          * \note ast_dsp_new() creates the DSP controller.
292          * \note Must use ast_dsp_free() to clean up. 
293          */
294         struct ast_dsp *dsp;
295
296         /*!
297          * \brief Allocated audio frame sample translator
298          * \note ast_translator_build_path() creates the translator path.
299          * \note Must use ast_translator_free_path() to clean up. 
300          */
301         struct ast_trans_pvt *trans;
302   
303         /*!
304          * \brief Associated Asterisk channel structure.
305          */
306         struct ast_channel * ast;
307
308         //int dummy;    /* Not used */
309   
310         /*!
311          * \brief Associated B channel structure.
312          */
313         struct misdn_bchannel *bc;
314
315         /*!
316          * \brief HOLDED channel information
317          */
318         struct hold_info hold_info;
319
320         /*! 
321          * \brief From associated B channel: Layer 3 process ID 
322          * \note Used to find the HOLDED channel call record when retrieving a call. 
323          */
324         unsigned int l3id;
325
326         /*! 
327          * \brief From associated B channel: B Channel mISDN driver layer ID from mISDN_get_layerid()
328          * \note Used only for debug display messages.
329          */
330         int addr;
331
332         /*!
333          * \brief Incoming call dialplan context identifier.
334          * \note The "context" string read in from /etc/asterisk/misdn.conf
335          */
336         char context[AST_MAX_CONTEXT];
337
338         /*!
339          * \brief The configured music-on-hold class to use for this call.
340          * \note The "musicclass" string read in from /etc/asterisk/misdn.conf
341          */
342         char mohinterpret[MAX_MUSICCLASS];
343
344 #if 0
345         int zero_read_cnt;      /* Not used */
346 #endif
347
348         /*!
349          * \brief Number of outgoing audio frames dropped since last debug gripe message.
350          */
351         int dropped_frame_cnt;
352
353         /*!
354          * \brief TRUE if we must do the ringback tones.
355          * \note The "far_alerting" boolean read in from /etc/asterisk/misdn.conf
356          */
357         int far_alerting;
358
359         /*!
360          * \brief TRUE if NT should disconnect an overlap dialing call when a timeout occurs.
361          * \note The "nttimeout" boolean read in from /etc/asterisk/misdn.conf
362          */
363         int nttimeout;
364
365         /*!
366          * \brief Other channel call record PID 
367          * \note Value imported from Asterisk environment variable MISDN_PID 
368          */
369         int other_pid;
370
371         /*!
372          * \brief Bridged other channel call record
373          * \note Pointer set when other_pid imported from Asterisk environment 
374          * variable MISDN_PID by either side.
375          */
376         struct chan_list *other_ch;
377
378         /*!
379          * \brief Tone zone sound used for dialtone generation.
380          * \note Used as a boolean.  Non-NULL to prod generation if enabled. 
381          */
382         struct ast_tone_zone_sound *ts;
383         
384         /*!
385          * \brief Enables overlap dialing for the set amount of seconds.  (0 = Disabled)
386          * \note The "overlapdial" value read in from /etc/asterisk/misdn.conf
387          */
388         int overlap_dial;
389
390         /*!
391          * \brief Overlap dialing timeout Task ID.  -1 if not running.
392          */
393         int overlap_dial_task;
394
395         /*!
396          * \brief overlap_tv access lock.
397          */
398         ast_mutex_t overlap_tv_lock;
399
400         /*!
401          * \brief Overlap timer start time.  Timer restarted for every digit received.
402          */
403         struct timeval overlap_tv;
404
405 #if 0
406         struct chan_list *peer;     /* Not used */
407 #endif
408
409         /*!
410          * \brief Next channel call record in the list.
411          */
412         struct chan_list *next;
413 #if 0
414         struct chan_list *prev;     /* Not used */
415         struct chan_list *first;    /* Not used */
416 #endif
417 };
418
419
420 int MAXTICS = 8;
421
422
423 void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch);
424 void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch);
425 static struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame);
426
427 static struct robin_list {
428         char *group;
429         int port;
430         int channel;
431         struct robin_list *next;
432         struct robin_list *prev;
433 } *robin = NULL;
434
435
436 static inline void free_robin_list_r(struct robin_list *r)
437 {
438         if (r) {
439                 if (r->next)
440                         free_robin_list_r(r->next);
441                 if (r->group)
442                         ast_free(r->group);
443                 ast_free(r);
444         }
445 }
446
447 static void free_robin_list(void)
448 {
449         free_robin_list_r(robin);
450         robin = NULL;
451 }
452
453 static struct robin_list* get_robin_position(char *group) 
454 {
455         struct robin_list *new;
456         struct robin_list *iter = robin;
457         for (; iter; iter = iter->next) {
458                 if (!strcasecmp(iter->group, group)) {
459                         return iter;
460                 }
461         }
462         new = ast_calloc(1, sizeof(*new));
463         new->group = strdup(group);
464         new->channel = 1;
465         if (robin) {
466                 new->next = robin;
467                 robin->prev = new;
468         }
469         robin = new;
470         return robin;
471 }
472
473
474 /*! \brief the main schedule context for stuff like l1 watcher, overlap dial, ... */
475 static struct sched_context *misdn_tasks = NULL;
476 static pthread_t misdn_tasks_thread;
477
478 static int *misdn_ports;
479
480 static void chan_misdn_log(int level, int port, char *tmpl, ...)
481         __attribute__((format(printf, 3, 4)));
482
483 static struct ast_channel *misdn_new(struct chan_list *cl, int state,  char *exten, char *callerid, int format, int port, int c);
484 static void send_digit_to_chan(struct chan_list *cl, char digit );
485
486 static void hangup_chan(struct chan_list *ch);
487 static int pbx_start_chan(struct chan_list *ch);
488
489 #define MISDN_ASTERISK_TECH_PVT(ast) ast->tech_pvt
490 #define MISDN_ASTERISK_PVT(ast) 1
491
492 #include "asterisk/strings.h"
493
494 /* #define MISDN_DEBUG 1 */
495
496 static const char misdn_type[] = "mISDN";
497
498 static int tracing = 0;
499
500 /*! \brief Only alaw and mulaw is allowed for now */
501 static int prefformat =  AST_FORMAT_ALAW ; /*  AST_FORMAT_SLINEAR ;  AST_FORMAT_ULAW | */
502
503 static int *misdn_debug;
504 static int *misdn_debug_only;
505 static int max_ports;
506
507 static int *misdn_in_calls;
508 static int *misdn_out_calls;
509
510 struct chan_list dummy_cl;
511
512 /*!
513  * \brief Global channel call record list head.
514  */
515 struct chan_list *cl_te=NULL;
516 ast_mutex_t cl_te_lock;
517
518 static enum event_response_e
519 cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data);
520
521 static void send_cause2ast(struct ast_channel *ast, struct misdn_bchannel*bc, struct chan_list *ch);
522
523 static void cl_queue_chan(struct chan_list **list, struct chan_list *chan);
524 static void cl_dequeue_chan(struct chan_list **list, struct chan_list *chan);
525 static struct chan_list *find_chan_by_bc(struct chan_list *list, struct misdn_bchannel *bc);
526 static struct chan_list *find_chan_by_pid(struct chan_list *list, int pid);
527
528 static int dialtone_indicate(struct chan_list *cl);
529 static int hanguptone_indicate(struct chan_list *cl);
530 static int stop_indicate(struct chan_list *cl);
531
532 static int start_bc_tones(struct chan_list *cl);
533 static int stop_bc_tones(struct chan_list *cl);
534 static void release_chan(struct misdn_bchannel *bc);
535
536 static int misdn_check_l2l1(struct ast_channel *chan, void *data);
537 static int misdn_set_opt_exec(struct ast_channel *chan, void *data);
538 static int misdn_facility_exec(struct ast_channel *chan, void *data);
539
540 int chan_misdn_jb_empty(struct misdn_bchannel *bc, char *buf, int len);
541
542 void debug_numplan(int port, int numplan, char *type);
543
544 int add_out_calls(int port);
545 int add_in_calls(int port);
546
547
548 #ifdef MISDN_1_2
549 static int update_pipeline_config(struct misdn_bchannel *bc);
550 #else
551 static int update_ec_config(struct misdn_bchannel *bc);
552 #endif
553
554
555
556 /*************** Helpers *****************/
557
558 static struct chan_list * get_chan_by_ast(struct ast_channel *ast)
559 {
560         struct chan_list *tmp;
561   
562         for (tmp = cl_te; tmp; tmp = tmp->next) {
563                 if (tmp->ast == ast) {
564                         return tmp;
565                 }
566         }
567   
568         return NULL;
569 }
570
571 static struct chan_list * get_chan_by_ast_name(char *name)
572 {
573         struct chan_list *tmp;
574   
575         for (tmp = cl_te; tmp; tmp = tmp->next) {
576                 if (tmp->ast && strcmp(tmp->ast->name, name) == 0) {
577                         return tmp;
578                 }
579         }
580   
581         return NULL;
582 }
583
584
585
586 struct allowed_bearers {
587         char *name;         /*!< Bearer capability name string used in /etc/misdn.conf allowed_bearers */
588         char *display;      /*!< Bearer capability displayable name */
589         int cap;            /*!< SETUP message bearer capability field code value */
590         int deprecated;     /*!< TRUE if this entry is deprecated. (Misspelled or bad name to use) */
591 };
592
593 /* *INDENT-OFF* */
594 static const struct allowed_bearers allowed_bearers_array[]= {
595         /* Name,                      Displayable Name       Bearer Capability,                    Deprecated */
596         { "speech",                  "Speech",               INFO_CAPABILITY_SPEECH,               0 },
597         { "3_1khz",                  "3.1KHz Audio",         INFO_CAPABILITY_AUDIO_3_1K,           0 },
598         { "digital_unrestricted",    "Unrestricted Digital", INFO_CAPABILITY_DIGITAL_UNRESTRICTED, 0 },
599         { "digital_restricted",      "Restricted Digital",   INFO_CAPABILITY_DIGITAL_RESTRICTED,   0 },
600         { "digital_restriced",       "Restricted Digital",   INFO_CAPABILITY_DIGITAL_RESTRICTED,   1 }, /* Allow misspelling for backwards compatibility */
601         { "video",                   "Video",                INFO_CAPABILITY_VIDEO,                0 }
602 };
603 /* *INDENT-ON* */
604
605 static const char *bearer2str(int cap)
606 {
607         unsigned index;
608
609         for (index = 0; index < ARRAY_LEN(allowed_bearers_array); ++index) {
610                 if (allowed_bearers_array[index].cap == cap) {
611                         return allowed_bearers_array[index].display;
612                 }
613         }       /* end for */
614
615         return "Unknown Bearer";
616 }
617
618
619 static void print_facility(struct FacParm *fac, struct misdn_bchannel *bc)
620 {
621         switch (fac->Function) {
622 #ifdef HAVE_MISDN_FAC_RESULT
623         case Fac_RESULT:
624                 chan_misdn_log(0, bc->port, " --> Received RESULT Operation\n");
625                 break;
626 #endif
627 #ifdef HAVE_MISDN_FAC_ERROR
628         case Fac_ERROR:
629                 chan_misdn_log(0, bc->port, " --> Received Error Operation\n");
630                 chan_misdn_log(0, bc->port, " --> Value:%d Error:%s\n", fac->u.ERROR.errorValue, fac->u.ERROR.error);
631                 break;
632 #endif
633         case Fac_CD:
634                 chan_misdn_log(1, bc->port, " --> calldeflect to: %s, presentable: %s\n", fac->u.CDeflection.DeflectedToNumber,
635                         fac->u.CDeflection.PresentationAllowed ? "yes" : "no");
636                 break;
637         case Fac_AOCDCurrency:
638                 if (fac->u.AOCDcur.chargeNotAvailable) {
639                         chan_misdn_log(1, bc->port, " --> AOCD currency: charge not available\n");
640                 } else if (fac->u.AOCDcur.freeOfCharge) {
641                         chan_misdn_log(1, bc->port, " --> AOCD currency: free of charge\n");
642                 } else if (fac->u.AOCDchu.billingId >= 0) {
643                         chan_misdn_log(1, bc->port, " --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s billingId:%d\n",
644                                 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
645                                 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId);
646                 } else {
647                         chan_misdn_log(1, bc->port, " --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s\n",
648                                 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
649                                 (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total");
650                 }
651                 break;
652         case Fac_AOCDChargingUnit:
653                 if (fac->u.AOCDchu.chargeNotAvailable) {
654                         chan_misdn_log(1, bc->port, " --> AOCD charging unit: charge not available\n");
655                 } else if (fac->u.AOCDchu.freeOfCharge) {
656                         chan_misdn_log(1, bc->port, " --> AOCD charging unit: free of charge\n");
657                 } else if (fac->u.AOCDchu.billingId >= 0) {
658                         chan_misdn_log(1, bc->port, " --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n",
659                                 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId);
660                 } else {
661                         chan_misdn_log(1, bc->port, " --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n",
662                                 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total");
663                 }
664                 break;
665         case Fac_None:
666         default:
667                 chan_misdn_log(1, bc->port, " --> unknown facility\n");
668                 break;
669         }
670 }
671
672 static void print_bearer(struct misdn_bchannel *bc) 
673 {
674         chan_misdn_log(2, bc->port, " --> Bearer: %s\n", bearer2str(bc->capability));
675         
676         switch(bc->law) {
677         case INFO_CODEC_ALAW:
678                 chan_misdn_log(2, bc->port, " --> Codec: Alaw\n");
679                 break;
680         case INFO_CODEC_ULAW:
681                 chan_misdn_log(2, bc->port, " --> Codec: Ulaw\n");
682                 break;
683         }
684 }
685
686 static void export_aoc_vars(int originator, struct ast_channel *ast, struct misdn_bchannel *bc)
687 {
688         char buf[128];
689
690         if (!bc->AOCD_need_export || !ast) {
691                 return;
692         }
693
694         if (originator == ORG_AST) {
695                 if (!(ast = ast_bridged_channel(ast))) {
696                         return;
697                 }
698         }
699
700         switch (bc->AOCDtype) {
701         case Fac_AOCDCurrency:
702                 pbx_builtin_setvar_helper(ast, "AOCD_Type", "currency");
703                 if (bc->AOCD.currency.chargeNotAvailable) {
704                         pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no");
705                 } else {
706                         pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes");
707                         if (bc->AOCD.currency.freeOfCharge) {
708                                 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes");
709                         } else {
710                                 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no");
711                                 if (snprintf(buf, sizeof(buf), "%d %s", bc->AOCD.currency.currencyAmount * bc->AOCD.currency.multiplier, bc->AOCD.currency.currency) < sizeof(buf)) {
712                                         pbx_builtin_setvar_helper(ast, "AOCD_Amount", buf);
713                                         if (bc->AOCD.currency.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.currency.billingId) < sizeof(buf)) {
714                                                 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf);
715                                         }
716                                 }
717                         }
718                 }
719                 break;
720         case Fac_AOCDChargingUnit:
721                 pbx_builtin_setvar_helper(ast, "AOCD_Type", "charging_unit");
722                 if (bc->AOCD.chargingUnit.chargeNotAvailable) {
723                         pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "no");
724                 } else {
725                         pbx_builtin_setvar_helper(ast, "AOCD_ChargeAvailable", "yes");
726                         if (bc->AOCD.chargingUnit.freeOfCharge) {
727                                 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "yes");
728                         } else {
729                                 pbx_builtin_setvar_helper(ast, "AOCD_FreeOfCharge", "no");
730                                 if (snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.recordedUnits) < sizeof(buf)) {
731                                         pbx_builtin_setvar_helper(ast, "AOCD_RecordedUnits", buf);
732                                         if (bc->AOCD.chargingUnit.billingId >= 0 && snprintf(buf, sizeof(buf), "%d", bc->AOCD.chargingUnit.billingId) < sizeof(buf)) {
733                                                 pbx_builtin_setvar_helper(ast, "AOCD_BillingId", buf);
734                                         }
735                                 }
736                         }
737                 }
738                 break;
739         default:
740                 break;
741         }
742         
743         bc->AOCD_need_export = 0;
744 }
745
746 /*************** Helpers END *************/
747
748 static void sighandler(int sig)
749 {}
750
751 static void *misdn_tasks_thread_func(void *data)
752 {
753         int wait;
754         struct sigaction sa;
755
756         sa.sa_handler = sighandler;
757         sa.sa_flags = SA_NODEFER;
758         sigemptyset(&sa.sa_mask);
759         sigaddset(&sa.sa_mask, SIGUSR1);
760         sigaction(SIGUSR1, &sa, NULL);
761         
762         sem_post((sem_t *)data);
763
764         while (1) {
765                 wait = ast_sched_wait(misdn_tasks);
766                 if (wait < 0) {
767                         wait = 8000;
768                 }
769                 if (poll(NULL, 0, wait) < 0) {
770                         chan_misdn_log(4, 0, "Waking up misdn_tasks thread\n");
771                 }
772                 ast_sched_runq(misdn_tasks);
773         }
774         return NULL;
775 }
776
777 static void misdn_tasks_init(void)
778 {
779         sem_t blocker;
780         int i = 5;
781
782         if (sem_init(&blocker, 0, 0)) {
783                 perror("chan_misdn: Failed to initialize semaphore!");
784                 exit(1);
785         }
786
787         chan_misdn_log(4, 0, "Starting misdn_tasks thread\n");
788         
789         misdn_tasks = sched_context_create();
790         pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, &blocker);
791
792         while (sem_wait(&blocker) && --i);
793         sem_destroy(&blocker);
794 }
795
796 static void misdn_tasks_destroy(void)
797 {
798         if (misdn_tasks) {
799                 chan_misdn_log(4, 0, "Killing misdn_tasks thread\n");
800                 if ( pthread_cancel(misdn_tasks_thread) == 0 ) {
801                         cb_log(4, 0, "Joining misdn_tasks thread\n");
802                         pthread_join(misdn_tasks_thread, NULL);
803                 }
804                 sched_context_destroy(misdn_tasks);
805         }
806 }
807
808 static inline void misdn_tasks_wakeup(void)
809 {
810         pthread_kill(misdn_tasks_thread, SIGUSR1);
811 }
812
813 static inline int _misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data, int variable)
814 {
815         int task_id;
816
817         if (!misdn_tasks) {
818                 misdn_tasks_init();
819         }
820         task_id = ast_sched_add_variable(misdn_tasks, timeout, callback, data, variable);
821         misdn_tasks_wakeup();
822
823         return task_id;
824 }
825
826 static int misdn_tasks_add(int timeout, ast_sched_cb callback, const void *data)
827 {
828         return _misdn_tasks_add_variable(timeout, callback, data, 0);
829 }
830
831 static int misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data)
832 {
833         return _misdn_tasks_add_variable(timeout, callback, data, 1);
834 }
835
836 static void misdn_tasks_remove(int task_id)
837 {
838         AST_SCHED_DEL(misdn_tasks, task_id);
839 }
840
841 static int misdn_l1_task(const void *vdata)
842 {
843         const int *data = vdata;
844         misdn_lib_isdn_l1watcher(*data);
845         chan_misdn_log(5, *data, "L1watcher timeout\n");
846         return 1;
847 }
848
849 static int misdn_overlap_dial_task(const void *data)
850 {
851         struct timeval tv_end, tv_now;
852         int diff;
853         struct chan_list *ch = (struct chan_list *) data;
854         char *dad;
855
856         chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", ch->state);
857
858         if (ch->state != MISDN_WAITING4DIGS) {
859                 ch->overlap_dial_task = -1;
860                 return 0;
861         }
862
863         ast_mutex_lock(&ch->overlap_tv_lock);
864         tv_end = ch->overlap_tv;
865         ast_mutex_unlock(&ch->overlap_tv_lock);
866
867         tv_end.tv_sec += ch->overlap_dial;
868         tv_now = ast_tvnow();
869
870         if ((diff = ast_tvdiff_ms(tv_end, tv_now)) > 100) {
871                 return diff;
872         }
873
874         /* if we are 100ms near the timeout, we are satisfied.. */
875         stop_indicate(ch);
876
877         if (ast_strlen_zero(ch->bc->dad)) {
878                 dad = "s";
879                 ast_copy_string(ch->ast->exten, "s", sizeof(ch->ast->exten));
880         } else {
881                 dad = ch->bc->dad;
882         }
883
884         if (ast_exists_extension(ch->ast, ch->context, dad, 1, ch->bc->oad)) {
885                 ch->state = MISDN_DIALING;
886                 if (pbx_start_chan(ch) < 0) {
887                         chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
888                         goto misdn_overlap_dial_task_disconnect;
889                 }
890         } else {
891 misdn_overlap_dial_task_disconnect:
892                 hanguptone_indicate(ch);
893                 ch->bc->out_cause = AST_CAUSE_UNALLOCATED;
894                 ch->state = MISDN_CLEANING;
895                 misdn_lib_send_event(ch->bc, EVENT_DISCONNECT);
896         }
897         ch->overlap_dial_task = -1;
898         return 0;
899 }
900
901 static void send_digit_to_chan(struct chan_list *cl, char digit)
902 {
903         static const char *dtmf_tones[] = {
904                 "!941+1336/100,!0/100", /* 0 */
905                 "!697+1209/100,!0/100", /* 1 */
906                 "!697+1336/100,!0/100", /* 2 */
907                 "!697+1477/100,!0/100", /* 3 */
908                 "!770+1209/100,!0/100", /* 4 */
909                 "!770+1336/100,!0/100", /* 5 */
910                 "!770+1477/100,!0/100", /* 6 */
911                 "!852+1209/100,!0/100", /* 7 */
912                 "!852+1336/100,!0/100", /* 8 */
913                 "!852+1477/100,!0/100", /* 9 */
914                 "!697+1633/100,!0/100", /* A */
915                 "!770+1633/100,!0/100", /* B */
916                 "!852+1633/100,!0/100", /* C */
917                 "!941+1633/100,!0/100", /* D */
918                 "!941+1209/100,!0/100", /* * */
919                 "!941+1477/100,!0/100", /* # */
920         };
921         struct ast_channel *chan = cl->ast; 
922   
923         if (digit >= '0' && digit <='9') {
924                 ast_playtones_start(chan, 0, dtmf_tones[digit - '0'], 0);
925         } else if (digit >= 'A' && digit <= 'D') {
926                 ast_playtones_start(chan, 0, dtmf_tones[digit - 'A' + 10], 0);
927         } else if (digit == '*') {
928                 ast_playtones_start(chan, 0, dtmf_tones[14], 0);
929         } else if (digit == '#') {
930                 ast_playtones_start(chan, 0, dtmf_tones[15], 0);
931         } else {
932                 /* not handled */
933                 ast_debug(1, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
934         }
935 }
936
937 /*** CLI HANDLING ***/
938 static char *handle_cli_misdn_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
939 {
940         int level;
941
942         switch (cmd) {
943         case CLI_INIT:
944                 e->command = "misdn set debug [on|off]";
945                 e->usage =
946                         "Usage: misdn set debug {on|off|<level>} [only] | [port <port> [only]]\n"
947                         "       Set the debug level of the mISDN channel.\n";
948                 return NULL;
949         case CLI_GENERATE:
950                 return complete_debug_port(a);
951         }
952
953         if (a->argc < 4 || a->argc > 7) {
954                 return CLI_SHOWUSAGE;
955         }
956
957         if (!strcasecmp(a->argv[3], "on")) {
958                 level = 1;
959         } else if (!strcasecmp(a->argv[3], "off")) {
960                 level = 0;
961         } else {
962                 level = atoi(a->argv[3]);
963         }
964
965         switch (a->argc) {
966         case 4:
967         case 5:
968                 {
969                         int i;
970                         int only = 0;
971                         if (a->argc == 5) {
972                                 if (strncasecmp(a->argv[4], "only", strlen(a->argv[4]))) {
973                                         return CLI_SHOWUSAGE;
974                                 } else {
975                                         only = 1;
976                                 }
977                         }
978         
979                         for (i = 0; i <= max_ports; i++) {
980                                 misdn_debug[i] = level;
981                                 misdn_debug_only[i] = only;
982                         }
983                         ast_cli(a->fd, "changing debug level for all ports to %d%s\n", misdn_debug[0], only ? " (only)" : "");
984                 }
985                 break;
986         case 6:
987         case 7:
988                 {
989                         int port;
990                         if (strncasecmp(a->argv[4], "port", strlen(a->argv[4])))
991                                 return CLI_SHOWUSAGE;
992                         port = atoi(a->argv[5]);
993                         if (port <= 0 || port > max_ports) {
994                                 switch (max_ports) {
995                                 case 0:
996                                         ast_cli(a->fd, "port number not valid! no ports available so you won't get lucky with any number here...\n");
997                                         break;
998                                 case 1:
999                                         ast_cli(a->fd, "port number not valid! only port 1 is available.\n");
1000                                         break;
1001                                 default:
1002                                         ast_cli(a->fd, "port number not valid! only ports 1 to %d are available.\n", max_ports);
1003                                 }
1004                                 return 0;
1005                         }
1006                         if (a->argc == 7) {
1007                                 if (strncasecmp(a->argv[6], "only", strlen(a->argv[6]))) {
1008                                         return CLI_SHOWUSAGE;
1009                                 } else {
1010                                         misdn_debug_only[port] = 1;
1011                                 }
1012                         } else {
1013                                 misdn_debug_only[port] = 0;
1014                         }
1015                         misdn_debug[port] = level;
1016                         ast_cli(a->fd, "changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port] ? " (only)" : "", port);
1017                 }
1018         }
1019
1020         return CLI_SUCCESS;
1021 }
1022
1023 static char *handle_cli_misdn_set_crypt_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1024 {
1025         switch (cmd) {
1026         case CLI_INIT:
1027                 e->command = "misdn set crypt debug";
1028                 e->usage =
1029                         "Usage: misdn set crypt debug <level>\n"
1030                         "       Set the crypt debug level of the mISDN channel. Level\n"
1031                         "       must be 1 or 2.\n";
1032                 return NULL;
1033         case CLI_GENERATE:
1034                 return NULL;
1035         }
1036
1037         if (a->argc != 5) {
1038                 return CLI_SHOWUSAGE;
1039         }
1040
1041         /* XXX Is this supposed to not do anything? XXX */
1042
1043         return CLI_SUCCESS;
1044 }
1045
1046 static char *handle_cli_misdn_port_block(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1047 {
1048         switch (cmd) {
1049         case CLI_INIT:
1050                 e->command = "misdn port block";
1051                 e->usage =
1052                         "Usage: misdn port block <port>\n"
1053                         "       Block the specified port by <port>.\n";
1054                 return NULL;
1055         case CLI_GENERATE:
1056                 return NULL;
1057         }
1058
1059         if (a->argc != 4) {
1060                 return CLI_SHOWUSAGE;
1061         }
1062
1063         misdn_lib_port_block(atoi(a->argv[3]));
1064
1065         return CLI_SUCCESS;
1066 }
1067
1068 static char *handle_cli_misdn_port_unblock(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1069 {
1070         switch (cmd) {
1071         case CLI_INIT:
1072                 e->command = "misdn port unblock";
1073                 e->usage =
1074                         "Usage: misdn port unblock <port>\n"
1075                         "       Unblock the port specified by <port>.\n";
1076                 return NULL;
1077         case CLI_GENERATE:
1078                 return NULL;
1079         }
1080
1081         if (a->argc != 4) {
1082                 return CLI_SHOWUSAGE;
1083         }
1084
1085         misdn_lib_port_unblock(atoi(a->argv[3]));
1086
1087         return CLI_SUCCESS;
1088 }
1089
1090 static char *handle_cli_misdn_restart_port(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1091 {
1092         switch (cmd) {
1093         case CLI_INIT:
1094                 e->command = "misdn restart port";
1095                 e->usage =
1096                         "Usage: misdn restart port <port>\n"
1097                         "       Restart the given port.\n";
1098                 return NULL;
1099         case CLI_GENERATE:
1100                 return NULL;
1101         }
1102
1103         if (a->argc != 4) {
1104                 return CLI_SHOWUSAGE;
1105         }
1106
1107         misdn_lib_port_restart(atoi(a->argv[3]));
1108
1109         return CLI_SUCCESS;
1110 }
1111
1112 static char *handle_cli_misdn_restart_pid(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1113 {
1114         switch (cmd) {
1115         case CLI_INIT:
1116                 e->command = "misdn restart pid";
1117                 e->usage =
1118                         "Usage: misdn restart pid <pid>\n"
1119                         "       Restart the given pid\n";
1120                 return NULL;
1121         case CLI_GENERATE:
1122                 return NULL;
1123         }
1124
1125         if (a->argc != 4) {
1126                 return CLI_SHOWUSAGE;
1127         }
1128
1129         misdn_lib_pid_restart(atoi(a->argv[3]));
1130
1131         return CLI_SUCCESS;
1132 }
1133
1134 static char *handle_cli_misdn_port_up(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1135 {
1136         switch (cmd) {
1137         case CLI_INIT:
1138                 e->command = "misdn port up";
1139                 e->usage =
1140                         "Usage: misdn port up <port>\n"
1141                         "       Try to establish L1 on the given port.\n";
1142                 return NULL;
1143         case CLI_GENERATE:
1144                 return NULL;
1145         }
1146
1147         if (a->argc != 4) {
1148                 return CLI_SHOWUSAGE;
1149         }
1150
1151         misdn_lib_get_port_up(atoi(a->argv[3]));
1152
1153         return CLI_SUCCESS;
1154 }
1155
1156 static char *handle_cli_misdn_port_down(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1157 {
1158         switch (cmd) {
1159         case CLI_INIT:
1160                 e->command = "misdn port down";
1161                 e->usage =
1162                         "Usage: misdn port down <port>\n"
1163                         "       Try to deactivate the L1 on the given port.\n";
1164                 return NULL;
1165         case CLI_GENERATE:
1166                 return NULL;
1167         }
1168
1169         if (a->argc != 4) {
1170                 return CLI_SHOWUSAGE;
1171         }
1172
1173         misdn_lib_get_port_down(atoi(a->argv[3]));
1174
1175         return CLI_SUCCESS;
1176 }
1177
1178 static inline void show_config_description(int fd, enum misdn_cfg_elements elem)
1179 {
1180         char section[BUFFERSIZE];
1181         char name[BUFFERSIZE];
1182         char desc[BUFFERSIZE];
1183         char def[BUFFERSIZE];
1184         char tmp[BUFFERSIZE];
1185
1186         misdn_cfg_get_name(elem, tmp, sizeof(tmp));
1187         term_color(name, tmp, COLOR_BRWHITE, 0, sizeof(tmp));
1188         misdn_cfg_get_desc(elem, desc, sizeof(desc), def, sizeof(def));
1189
1190         if (elem < MISDN_CFG_LAST) {
1191                 term_color(section, "PORTS SECTION", COLOR_YELLOW, 0, sizeof(section));
1192         } else {
1193                 term_color(section, "GENERAL SECTION", COLOR_YELLOW, 0, sizeof(section));
1194         }
1195
1196         if (*def) {
1197                 ast_cli(fd, "[%s] %s   (Default: %s)\n\t%s\n", section, name, def, desc);
1198         } else {
1199                 ast_cli(fd, "[%s] %s\n\t%s\n", section, name, desc);
1200         }
1201 }
1202
1203 static char *handle_cli_misdn_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1204 {
1205         char buffer[BUFFERSIZE];
1206         enum misdn_cfg_elements elem;
1207         int linebreak;
1208         int onlyport = -1;
1209         int ok = 0;
1210
1211         switch (cmd) {
1212         case CLI_INIT:
1213                 e->command = "misdn show config";
1214                 e->usage =
1215                         "Usage: misdn show config [<port> | description <config element> | descriptions [general|ports]]\n"
1216                         "       Use 0 for <port> to only print the general config.\n";
1217                 return NULL;
1218         case CLI_GENERATE:
1219                 return complete_show_config(a);
1220         }
1221
1222         if (a->argc >= 4) {
1223                 if (!strcmp(a->argv[3], "description")) {
1224                         if (a->argc == 5) {
1225                                 enum misdn_cfg_elements elem = misdn_cfg_get_elem(a->argv[4]);
1226                                 if (elem == MISDN_CFG_FIRST) {
1227                                         ast_cli(a->fd, "Unknown element: %s\n", a->argv[4]);
1228                                 } else {
1229                                         show_config_description(a->fd, elem);
1230                                 }
1231                                 return CLI_SUCCESS;
1232                         }
1233                         return CLI_SHOWUSAGE;
1234                 } else if (!strcmp(a->argv[3], "descriptions")) {
1235                         if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "general"))) {
1236                                 for (elem = MISDN_GEN_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
1237                                         show_config_description(a->fd, elem);
1238                                         ast_cli(a->fd, "\n");
1239                                 }
1240                                 ok = 1;
1241                         }
1242                         if ((a->argc == 4) || ((a->argc == 5) && !strcmp(a->argv[4], "ports"))) {
1243                                 for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_CFG_LAST - 1 /* the ptp hack, remove the -1 when ptp is gone */; ++elem) {
1244                                         show_config_description(a->fd, elem);
1245                                         ast_cli(a->fd, "\n");
1246                                 }
1247                                 ok = 1;
1248                         }
1249                         return ok ? CLI_SUCCESS : CLI_SHOWUSAGE;
1250                 } else if (!sscanf(a->argv[3], "%d", &onlyport) || onlyport < 0) {
1251                         ast_cli(a->fd, "Unknown option: %s\n", a->argv[3]);
1252                         return CLI_SHOWUSAGE;
1253                 }
1254         } else if (a->argc == 3 || onlyport == 0) {
1255                 ast_cli(a->fd, "mISDN General-Config:\n");
1256                 for (elem = MISDN_GEN_FIRST + 1, linebreak = 1; elem < MISDN_GEN_LAST; elem++, linebreak++) {
1257                         misdn_cfg_get_config_string(0, elem, buffer, sizeof(buffer));
1258                         ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
1259                 }
1260                 ast_cli(a->fd, "\n");
1261         }
1262
1263         if (onlyport < 0) {
1264                 int port = misdn_cfg_get_next_port(0);
1265                 for (; port > 0; port = misdn_cfg_get_next_port(port)) {
1266                         ast_cli(a->fd, "\n[PORT %d]\n", port);
1267                         for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
1268                                 misdn_cfg_get_config_string(port, elem, buffer, sizeof(buffer));
1269                                 ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
1270                         }       
1271                         ast_cli(a->fd, "\n");
1272                 }
1273         }
1274         
1275         if (onlyport > 0) {
1276                 if (misdn_cfg_is_port_valid(onlyport)) {
1277                         ast_cli(a->fd, "[PORT %d]\n", onlyport);
1278                         for (elem = MISDN_CFG_FIRST + 1, linebreak = 1; elem < MISDN_CFG_LAST; elem++, linebreak++) {
1279                                 misdn_cfg_get_config_string(onlyport, elem, buffer, sizeof(buffer));
1280                                 ast_cli(a->fd, "%-36s%s", buffer, !(linebreak % 2) ? "\n" : "");
1281                         }       
1282                         ast_cli(a->fd, "\n");
1283                 } else {
1284                         ast_cli(a->fd, "Port %d is not active!\n", onlyport);
1285                 }
1286         }
1287
1288         return CLI_SUCCESS;
1289 }
1290
1291 struct state_struct {
1292         enum misdn_chan_state state;
1293         char txt[255];
1294 };
1295
1296 static struct state_struct state_array[] = {
1297         { MISDN_NOTHING,             "NOTHING" },             /* at beginning */
1298         { MISDN_WAITING4DIGS,        "WAITING4DIGS" },        /*  when waiting for infos */
1299         { MISDN_EXTCANTMATCH,        "EXTCANTMATCH" },        /*  when asterisk couldn't match our ext */
1300         { MISDN_INCOMING_SETUP,      "INCOMING SETUP" },      /*  when pbx_start */
1301         { MISDN_DIALING,             "DIALING" },             /*  when pbx_start */
1302         { MISDN_PROGRESS,            "PROGRESS" },            /*  when pbx_start */
1303         { MISDN_PROCEEDING,          "PROCEEDING" },          /*  when pbx_start */
1304         { MISDN_CALLING,             "CALLING" },             /*  when misdn_call is called */
1305         { MISDN_CALLING_ACKNOWLEDGE, "CALLING_ACKNOWLEDGE" }, /*  when misdn_call is called */
1306         { MISDN_ALERTING,            "ALERTING" },            /*  when Alerting */
1307         { MISDN_BUSY,                "BUSY" },                /*  when BUSY */
1308         { MISDN_CONNECTED,           "CONNECTED" },           /*  when connected */
1309         { MISDN_PRECONNECTED,        "PRECONNECTED" },        /*  when connected */
1310         { MISDN_DISCONNECTED,        "DISCONNECTED" },        /*  when connected */
1311         { MISDN_RELEASED,            "RELEASED" },            /*  when connected */
1312         { MISDN_BRIDGED,             "BRIDGED" },             /*  when bridged */
1313         { MISDN_CLEANING,            "CLEANING" },            /* when hangup from * but we were connected before */
1314         { MISDN_HUNGUP_FROM_MISDN,   "HUNGUP_FROM_MISDN" },   /* when DISCONNECT/RELEASE/REL_COMP  came from misdn */
1315         { MISDN_HOLDED,              "HOLDED" },              /* when DISCONNECT/RELEASE/REL_COMP  came from misdn */
1316         { MISDN_HOLD_DISCONNECT,     "HOLD_DISCONNECT" },     /* when DISCONNECT/RELEASE/REL_COMP  came from misdn */
1317         { MISDN_HUNGUP_FROM_AST,     "HUNGUP_FROM_AST" },     /* when DISCONNECT/RELEASE/REL_COMP came out of misdn_hangup */
1318 };
1319
1320 static const char *misdn_get_ch_state(struct chan_list *p) 
1321 {
1322         int i;
1323         static char state[8];
1324         
1325         if (!p) {
1326                 return NULL;
1327         }
1328   
1329         for (i = 0; i < ARRAY_LEN(state_array); i++) {
1330                 if (state_array[i].state == p->state) {
1331                         return state_array[i].txt;
1332                 }
1333         }
1334
1335         snprintf(state, sizeof(state), "%d", p->state) ;
1336
1337         return state;
1338 }
1339
1340
1341 static void reload_config(void)
1342 {
1343         int i, cfg_debug;
1344
1345         if (!g_config_initialized) {
1346                 ast_log(LOG_WARNING, "chan_misdn is not initialized properly, still reloading ?\n");
1347                 return ;
1348         }
1349         
1350         free_robin_list();
1351         misdn_cfg_reload();
1352         misdn_cfg_update_ptp();
1353         misdn_cfg_get(0, MISDN_GEN_TRACEFILE, global_tracefile, sizeof(global_tracefile));
1354         misdn_cfg_get(0, MISDN_GEN_DEBUG, &cfg_debug, sizeof(cfg_debug));
1355
1356         for (i = 0;  i <= max_ports; i++) {
1357                 misdn_debug[i] = cfg_debug;
1358                 misdn_debug_only[i] = 0;
1359         }
1360 }
1361
1362 static char *handle_cli_misdn_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1363 {
1364         switch (cmd) {
1365         case CLI_INIT:
1366                 e->command = "misdn reload";
1367                 e->usage =
1368                         "Usage: misdn reload\n"
1369                         "       Reload internal mISDN config, read from the config\n"
1370                         "       file.\n";
1371                 return NULL;
1372         case CLI_GENERATE:
1373                 return NULL;
1374         }
1375
1376         if (a->argc != 2) {
1377                 return CLI_SHOWUSAGE;
1378         }
1379
1380         ast_cli(a->fd, "Reloading mISDN configuration\n");
1381         reload_config();
1382         return CLI_SUCCESS;
1383 }
1384
1385 static void print_bc_info (int fd, struct chan_list *help, struct misdn_bchannel *bc)
1386 {
1387         struct ast_channel *ast = help->ast;
1388         ast_cli(fd,
1389                 "* Pid:%d Prt:%d Ch:%d Mode:%s Org:%s dad:%s oad:%s rad:%s ctx:%s state:%s\n",
1390
1391                 bc->pid, bc->port, bc->channel,
1392                 bc->nt ? "NT" : "TE",
1393                 help->originator == ORG_AST ? "*" : "I",
1394                 ast ? ast->exten : NULL,
1395                 ast ? ast->cid.cid_num : NULL,
1396                 bc->rad,
1397                 ast ? ast->context : NULL,
1398                 misdn_get_ch_state(help)
1399                 );
1400         if (misdn_debug[bc->port] > 0) {
1401                 ast_cli(fd,
1402                         "  --> astname: %s\n"
1403                         "  --> ch_l3id: %x\n"
1404                         "  --> ch_addr: %x\n"
1405                         "  --> bc_addr: %x\n"
1406                         "  --> bc_l3id: %x\n"
1407                         "  --> display: %s\n"
1408                         "  --> activated: %d\n"
1409                         "  --> state: %s\n"
1410                         "  --> capability: %s\n"
1411 #ifdef MISDN_1_2
1412                         "  --> pipeline: %s\n"
1413 #else
1414                         "  --> echo_cancel: %d\n"
1415 #endif
1416                         "  --> notone : rx %d tx:%d\n"
1417                         "  --> bc_hold: %d\n",
1418                         help->ast->name,
1419                         help->l3id,
1420                         help->addr,
1421                         bc->addr,
1422                         bc ? bc->l3_id : -1,
1423                         bc->display,
1424                         
1425                         bc->active,
1426                         bc_state2str(bc->bc_state),
1427                         bearer2str(bc->capability),
1428 #ifdef MISDN_1_2
1429                         bc->pipeline,
1430 #else
1431                         bc->ec_enable,
1432 #endif
1433
1434                         help->norxtone, help->notxtone,
1435                         bc->holded
1436                         );
1437         }
1438 }
1439
1440 static char *handle_cli_misdn_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1441 {
1442         struct chan_list *help;
1443
1444         switch (cmd) {
1445         case CLI_INIT:
1446                 e->command = "misdn show channels";
1447                 e->usage =
1448                         "Usage: misdn show channels\n"
1449                         "       Show the internal mISDN channel list\n";
1450                 return NULL;
1451         case CLI_GENERATE:
1452                 return NULL;
1453         }
1454
1455         if (a->argc != 3) {
1456                 return CLI_SHOWUSAGE;
1457         }
1458
1459         help = cl_te;
1460   
1461         ast_cli(a->fd, "Channel List: %p\n", cl_te);
1462
1463         for (; help; help = help->next) {
1464                 struct misdn_bchannel *bc = help->bc;   
1465                 struct ast_channel *ast = help->ast;
1466                 if (!ast) {
1467                         if (!bc) {
1468                                 ast_cli(a->fd, "chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->l3id);
1469                                 continue;
1470                         }
1471                         ast_cli(a->fd, "bc with pid:%d has no Ast Leg\n", bc->pid);
1472                         continue;
1473                 }
1474
1475                 if (misdn_debug[0] > 2) {
1476                         ast_cli(a->fd, "Bc:%p Ast:%p\n", bc, ast);
1477                 }
1478                 if (bc) {
1479                         print_bc_info(a->fd, help, bc);
1480                 } else {
1481                         if (help->state == MISDN_HOLDED) {
1482                                 ast_cli(a->fd, "ITS A HOLDED BC:\n");
1483                                 ast_cli(a->fd, " --> l3_id: %x\n"
1484                                                 " --> dad:%s oad:%s\n"
1485                                                 " --> hold_port: %d\n"
1486                                                 " --> hold_channel: %d\n",
1487                                                 help->l3id,
1488                                                 ast->exten,
1489                                                 ast->cid.cid_num,
1490                                                 help->hold_info.port,
1491                                                 help->hold_info.channel
1492                                                 );
1493                         } else {
1494                                 ast_cli(a->fd, "* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n", ast->exten, ast->cid.cid_num);
1495                         }
1496                 }
1497         }
1498
1499         misdn_dump_chanlist();
1500
1501         return CLI_SUCCESS;
1502 }
1503
1504 static char *handle_cli_misdn_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1505 {
1506         struct chan_list *help;
1507
1508         switch (cmd) {
1509         case CLI_INIT:
1510                 e->command = "misdn show channel";
1511                 e->usage =
1512                         "Usage: misdn show channel <channel>\n"
1513                         "       Show an internal mISDN channel\n.";
1514                 return NULL;
1515         case CLI_GENERATE:
1516                 return complete_ch(a);
1517         }
1518
1519         if (a->argc != 4) {
1520                 return CLI_SHOWUSAGE;
1521         }
1522
1523         help = cl_te;
1524
1525         for (; help; help = help->next) {
1526                 struct misdn_bchannel *bc = help->bc;   
1527                 struct ast_channel *ast = help->ast;
1528     
1529                 if (bc && ast) {
1530                         if (!strcasecmp(ast->name, a->argv[3])) {
1531                                 print_bc_info(a->fd, help, bc);
1532                                 break; 
1533                         }
1534                 }
1535         }
1536
1537         return CLI_SUCCESS;
1538 }
1539
1540 static char *handle_cli_misdn_set_tics(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1541 {
1542         switch (cmd) {
1543         case CLI_INIT:
1544                 e->command = "misdn set tics";
1545                 e->usage =
1546                         "Usage: misdn set tics <value>\n";
1547                 return NULL;
1548         case CLI_GENERATE:
1549                 return NULL;
1550         }
1551
1552         if (a->argc != 4) {
1553                 return CLI_SHOWUSAGE;
1554         }
1555
1556         /* XXX Wow, this does... a whole lot of nothing... XXX */
1557         MAXTICS = atoi(a->argv[3]);
1558
1559         return CLI_SUCCESS;
1560 }
1561
1562 static char *handle_cli_misdn_show_stacks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1563 {
1564         int port;
1565
1566         switch (cmd) {
1567         case CLI_INIT:
1568                 e->command = "misdn show stacks";
1569                 e->usage =
1570                         "Usage: misdn show stacks\n"
1571                         "       Show internal mISDN stack_list.\n";
1572                 return NULL;
1573         case CLI_GENERATE:
1574                 return NULL;
1575         }
1576
1577         if (a->argc != 3) {
1578                 return CLI_SHOWUSAGE;
1579         }
1580
1581         ast_cli(a->fd, "BEGIN STACK_LIST:\n");
1582         for (port = misdn_cfg_get_next_port(0); port > 0;
1583              port = misdn_cfg_get_next_port(port)) {
1584                 char buf[128];
1585                 get_show_stack_details(port, buf);
1586                 ast_cli(a->fd, "  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
1587         }
1588
1589         return CLI_SUCCESS;
1590 }
1591
1592 static char *handle_cli_misdn_show_ports_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1593 {
1594         int port;
1595
1596         switch (cmd) {
1597         case CLI_INIT:
1598                 e->command = "misdn show ports stats";
1599                 e->usage =
1600                         "Usage: misdn show ports stats\n"
1601                         "       Show mISDNs channel's call statistics per port.\n";
1602                 return NULL;
1603         case CLI_GENERATE:
1604                 return NULL;
1605         }
1606
1607         if (a->argc != 4) {
1608                 return CLI_SHOWUSAGE;
1609         }
1610
1611         ast_cli(a->fd, "Port\tin_calls\tout_calls\n");
1612         for (port = misdn_cfg_get_next_port(0); port > 0;
1613              port = misdn_cfg_get_next_port(port)) {
1614                 ast_cli(a->fd, "%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]);
1615         }
1616         ast_cli(a->fd, "\n");
1617
1618         return CLI_SUCCESS;
1619 }
1620
1621 static char *handle_cli_misdn_show_port(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1622 {
1623         int port;
1624         char buf[128];
1625
1626         switch (cmd) {
1627         case CLI_INIT:
1628                 e->command = "misdn show port";
1629                 e->usage =
1630                         "Usage: misdn show port <port>\n"
1631                         "       Show detailed information for given port.\n";
1632                 return NULL;
1633         case CLI_GENERATE:
1634                 return NULL;
1635         }
1636
1637         if (a->argc != 4) {
1638                 return CLI_SHOWUSAGE;
1639         }
1640
1641         port = atoi(a->argv[3]);
1642   
1643         ast_cli(a->fd, "BEGIN STACK_LIST:\n");
1644         get_show_stack_details(port, buf);
1645         ast_cli(a->fd, "  %s  Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ? "(only)" : "");
1646
1647         return CLI_SUCCESS;
1648 }
1649
1650 static char *handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1651 {
1652         char *channame; 
1653         char *nr;
1654         struct chan_list *tmp;
1655         int port; 
1656         char *served_nr;
1657         struct misdn_bchannel dummy, *bc=&dummy;
1658  
1659         switch (cmd) {
1660         case CLI_INIT:
1661                 e->command = "misdn send facility";
1662                 e->usage = "Usage: misdn send facility <type> <channel|port> \"<args>\" \n"
1663                 "\t type is one of:\n"
1664                 "\t - calldeflect\n"
1665                 "\t - CFActivate\n"
1666                 "\t - CFDeactivate\n";
1667
1668                 return NULL;
1669         case CLI_GENERATE:
1670                 return complete_ch(a);
1671         }
1672
1673         if (a->argc < 5) {
1674                 return CLI_SHOWUSAGE;
1675         }
1676  
1677         if (strstr(a->argv[3], "calldeflect")) {
1678                 if (a->argc < 6) {
1679                         ast_verbose("calldeflect requires 1 arg: ToNumber\n\n");
1680                         return 0;
1681                 }
1682                 channame = a->argv[4];
1683                 nr = a->argv[5];
1684
1685                 ast_verbose("Sending Calldeflection (%s) to %s\n", nr, channame);
1686                 tmp = get_chan_by_ast_name(channame);
1687                 if (!tmp) {
1688                         ast_verbose("Sending CD with nr %s to %s failed: Channel does not exist.\n", nr, channame);
1689                         return 0; 
1690                 }
1691
1692                 if (strlen(nr) >= 15) {
1693                         ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n", nr, channame);
1694                         return 0; 
1695                 }
1696                 tmp->bc->fac_out.Function = Fac_CD;
1697                 ast_copy_string((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber));
1698                 misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
1699         } else if (strstr(a->argv[3], "CFActivate")) {
1700                 if (a->argc < 7) {
1701                         ast_verbose("CFActivate requires 2 args: 1.FromNumber, 2.ToNumber\n\n");
1702                         return 0;
1703                 }
1704                 port = atoi(a->argv[4]);
1705                 served_nr = a->argv[5];
1706                 nr = a->argv[6];
1707
1708                 misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
1709
1710                 ast_verbose("Sending CFActivate  Port:(%d) FromNr. (%s) to Nr. (%s)\n", port, served_nr, nr);
1711
1712                 bc->fac_out.Function = Fac_CFActivate;
1713                 bc->fac_out.u.CFActivate.BasicService = 0; /* All Services */
1714                 bc->fac_out.u.CFActivate.Procedure = 0; /* Unconditional */
1715                 ast_copy_string((char *)bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
1716                 ast_copy_string((char *)bc->fac_out.u.CFActivate.ForwardedToNumber, nr, sizeof(bc->fac_out.u.CFActivate.ForwardedToNumber));
1717
1718                 misdn_lib_send_event(bc, EVENT_FACILITY);
1719         } else if (strstr(a->argv[3], "CFDeactivate")) {
1720
1721                 if (a->argc < 6) {
1722                         ast_verbose("CFActivate requires 1 arg: FromNumber\n\n");
1723                         return 0;
1724                 }
1725                 port = atoi(a->argv[4]);
1726                 served_nr = a->argv[5];
1727                 
1728                 misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
1729                 ast_verbose("Sending CFDeactivate  Port:(%d) FromNr. (%s)\n", port, served_nr);
1730
1731                 bc->fac_out.Function = Fac_CFDeactivate;
1732                 bc->fac_out.u.CFDeactivate.BasicService = 0; //All Services
1733                 bc->fac_out.u.CFDeactivate.Procedure = 0; //Unconditional
1734                 
1735                 ast_copy_string((char *)bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
1736                 misdn_lib_send_event(bc, EVENT_FACILITY);
1737         }
1738
1739         return CLI_SUCCESS;
1740 }
1741
1742 static char *handle_cli_misdn_send_restart(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1743 {
1744         int port;
1745         int channel;
1746
1747         switch (cmd) {
1748         case CLI_INIT:
1749                 e->command = "misdn send restart";
1750                 e->usage =
1751                         "Usage: misdn send restart [port [channel]]\n"
1752                         "       Send a restart for every bchannel on the given port.\n";
1753                 return NULL;
1754         case CLI_GENERATE:
1755                 return NULL;
1756         }
1757
1758         if (a->argc < 4 || a->argc > 5) {
1759                 return CLI_SHOWUSAGE;
1760         }
1761
1762         port = atoi(a->argv[3]);
1763
1764         if (a->argc == 5) {
1765                 channel = atoi(a->argv[4]);
1766                 misdn_lib_send_restart(port, channel);
1767         } else {
1768                 misdn_lib_send_restart(port, -1);
1769         }
1770
1771         return CLI_SUCCESS;
1772 }
1773
1774 static char *handle_cli_misdn_send_digit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1775 {
1776         char *channame; 
1777         char *msg; 
1778         struct chan_list *tmp;
1779         int i, msglen;
1780
1781         switch (cmd) {
1782         case CLI_INIT:
1783                 e->command = "misdn send digit";
1784                 e->usage =
1785                         "Usage: misdn send digit <channel> \"<msg>\" \n"
1786                         "       Send <digit> to <channel> as DTMF Tone\n"
1787                         "       when channel is a mISDN channel\n";
1788                 return NULL;
1789         case CLI_GENERATE:
1790                 return complete_ch(a);
1791         }
1792
1793         if (a->argc != 5) {
1794                 return CLI_SHOWUSAGE;
1795         }
1796
1797         channame = a->argv[3];
1798         msg = a->argv[4];
1799         msglen = strlen(msg);
1800
1801         ast_cli(a->fd, "Sending %s to %s\n", msg, channame);
1802
1803         tmp = get_chan_by_ast_name(channame);
1804         if (!tmp) {
1805                 ast_cli(a->fd, "Sending %s to %s failed Channel does not exist\n", msg, channame);
1806                 return CLI_SUCCESS; 
1807         }
1808 #if 1
1809         for (i = 0; i < msglen; i++) {
1810                 ast_cli(a->fd, "Sending: %c\n", msg[i]);
1811                 send_digit_to_chan(tmp, msg[i]);
1812                 /* res = ast_safe_sleep(tmp->ast, 250); */
1813                 usleep(250000);
1814                 /* res = ast_waitfor(tmp->ast,100); */
1815         }
1816 #else
1817         ast_dtmf_stream(tmp->ast, NULL, msg, 250);
1818 #endif
1819
1820         return CLI_SUCCESS;
1821 }
1822
1823 static char *handle_cli_misdn_toggle_echocancel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1824 {
1825         char *channame;
1826         struct chan_list *tmp;
1827
1828         switch (cmd) {
1829         case CLI_INIT:
1830                 e->command = "misdn toggle echocancel";
1831                 e->usage =
1832                         "Usage: misdn toggle echocancel <channel>\n"
1833                         "       Toggle EchoCancel on mISDN Channel.\n";
1834                 return NULL;
1835         case CLI_GENERATE:
1836                 return complete_ch(a);
1837         }
1838
1839         if (a->argc != 4) {
1840                 return CLI_SHOWUSAGE;
1841         }
1842
1843         channame = a->argv[3];
1844   
1845         ast_cli(a->fd, "Toggling EchoCancel on %s\n", channame);
1846   
1847         tmp = get_chan_by_ast_name(channame);
1848         if (!tmp) {
1849                 ast_cli(a->fd, "Toggling EchoCancel %s failed Channel does not exist\n", channame);
1850                 return CLI_SUCCESS;
1851         }
1852
1853         tmp->toggle_ec = tmp->toggle_ec ? 0 : 1;
1854
1855         if (tmp->toggle_ec) {
1856 #ifdef MISDN_1_2
1857                 update_pipeline_config(tmp->bc);
1858 #else
1859                 update_ec_config(tmp->bc);
1860 #endif
1861                 manager_ec_enable(tmp->bc);
1862         } else {
1863                 manager_ec_disable(tmp->bc);
1864         }
1865
1866         return CLI_SUCCESS;
1867 }
1868
1869 static char *handle_cli_misdn_send_display(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1870 {
1871         char *channame;
1872         char *msg;
1873         struct chan_list *tmp;
1874
1875         switch (cmd) {
1876         case CLI_INIT:
1877                 e->command = "misdn send display";
1878                 e->usage =
1879                         "Usage: misdn send display <channel> \"<msg>\" \n"
1880                         "       Send <msg> to <channel> as Display Message\n"
1881                         "       when channel is a mISDN channel\n";
1882                 return NULL;
1883         case CLI_GENERATE:
1884                 return complete_ch(a);
1885         }
1886
1887         if (a->argc != 5) {
1888                 return CLI_SHOWUSAGE;
1889         }
1890
1891         channame = a->argv[3];
1892         msg = a->argv[4];
1893
1894         ast_cli(a->fd, "Sending %s to %s\n", msg, channame);
1895         tmp = get_chan_by_ast_name(channame);
1896     
1897         if (tmp && tmp->bc) {
1898                 ast_copy_string(tmp->bc->display, msg, sizeof(tmp->bc->display));
1899                 misdn_lib_send_event(tmp->bc, EVENT_INFORMATION);
1900         } else {
1901                 ast_cli(a->fd, "No such channel %s\n", channame);
1902                 return CLI_SUCCESS;
1903         }
1904
1905         return CLI_SUCCESS;
1906 }
1907
1908 static char *complete_ch(struct ast_cli_args *a)
1909 {
1910         return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
1911 }
1912
1913 static char *complete_debug_port(struct ast_cli_args *a)
1914 {
1915         if (a->n) {
1916                 return NULL;
1917         }
1918
1919         switch (a->pos) {
1920         case 4:
1921                 if (a->word[0] == 'p') {
1922                         return ast_strdup("port");
1923                 } else if (a->word[0] == 'o') {
1924                         return ast_strdup("only");
1925                 }
1926                 break;
1927         case 6:
1928                 if (a->word[0] == 'o') {
1929                         return ast_strdup("only");
1930                 }
1931                 break;
1932         }
1933         return NULL;
1934 }
1935
1936 static char *complete_show_config(struct ast_cli_args *a)
1937 {
1938         char buffer[BUFFERSIZE];
1939         enum misdn_cfg_elements elem;
1940         int wordlen = strlen(a->word);
1941         int which = 0;
1942         int port = 0;
1943
1944         switch (a->pos) {
1945         case 3:
1946                 if ((!strncmp(a->word, "description", wordlen)) && (++which > a->n)) {
1947                         return ast_strdup("description");
1948                 }
1949                 if ((!strncmp(a->word, "descriptions", wordlen)) && (++which > a->n)) {
1950                         return ast_strdup("descriptions");
1951                 }
1952                 if ((!strncmp(a->word, "0", wordlen)) && (++which > a->n)) {
1953                         return ast_strdup("0");
1954                 }
1955                 while ((port = misdn_cfg_get_next_port(port)) != -1) {
1956                         snprintf(buffer, sizeof(buffer), "%d", port);
1957                         if ((!strncmp(a->word, buffer, wordlen)) && (++which > a->n)) {
1958                                 return ast_strdup(buffer);
1959                         }
1960                 }
1961                 break;
1962         case 4:
1963                 if (strstr(a->line, "description ")) {
1964                         for (elem = MISDN_CFG_FIRST + 1; elem < MISDN_GEN_LAST; ++elem) {
1965                                 if ((elem == MISDN_CFG_LAST) || (elem == MISDN_GEN_FIRST)) {
1966                                         continue;
1967                                 }
1968                                 misdn_cfg_get_name(elem, buffer, sizeof(buffer));
1969                                 if (!wordlen || !strncmp(a->word, buffer, wordlen)) {
1970                                         if (++which > a->n) {
1971                                                 return ast_strdup(buffer);
1972                                         }
1973                                 }
1974                         }
1975                 } else if (strstr(a->line, "descriptions ")) {
1976                         if ((!wordlen || !strncmp(a->word, "general", wordlen)) && (++which > a->n)) {
1977                                 return ast_strdup("general");
1978                         }
1979                         if ((!wordlen || !strncmp(a->word, "ports", wordlen)) && (++which > a->n)) {
1980                                 return ast_strdup("ports");
1981                         }
1982                 }
1983                 break;
1984         }
1985         return NULL;
1986 }
1987
1988 static struct ast_cli_entry chan_misdn_clis[] = {
1989         AST_CLI_DEFINE(handle_cli_misdn_port_block,        "Block the given port"),
1990         AST_CLI_DEFINE(handle_cli_misdn_port_down,         "Try to deactivate the L1 on the given port"),
1991         AST_CLI_DEFINE(handle_cli_misdn_port_unblock,      "Unblock the given port"),
1992         AST_CLI_DEFINE(handle_cli_misdn_port_up,           "Try to establish L1 on the given port"),
1993         AST_CLI_DEFINE(handle_cli_misdn_reload,            "Reload internal mISDN config, read from the config file"),
1994         AST_CLI_DEFINE(handle_cli_misdn_restart_pid,       "Restart the given pid"),
1995         AST_CLI_DEFINE(handle_cli_misdn_restart_port,      "Restart the given port"),
1996         AST_CLI_DEFINE(handle_cli_misdn_show_channel,      "Show an internal mISDN channel"),
1997         AST_CLI_DEFINE(handle_cli_misdn_show_channels,     "Show the internal mISDN channel list"),
1998         AST_CLI_DEFINE(handle_cli_misdn_show_config,       "Show internal mISDN config, read from the config file"),
1999         AST_CLI_DEFINE(handle_cli_misdn_show_port,         "Show detailed information for given port"),
2000         AST_CLI_DEFINE(handle_cli_misdn_show_ports_stats,  "Show mISDNs channel's call statistics per port"),
2001         AST_CLI_DEFINE(handle_cli_misdn_show_stacks,       "Show internal mISDN stack_list"),
2002         AST_CLI_DEFINE(handle_cli_misdn_send_facility,     "Sends a Facility Message to the mISDN Channel"),
2003         AST_CLI_DEFINE(handle_cli_misdn_send_digit,        "Send DTMF digit to mISDN Channel"),
2004         AST_CLI_DEFINE(handle_cli_misdn_send_display,      "Send Text to mISDN Channel"),
2005         AST_CLI_DEFINE(handle_cli_misdn_send_restart,      "Send a restart for every bchannel on the given port"),
2006         AST_CLI_DEFINE(handle_cli_misdn_set_crypt_debug,   "Set CryptDebuglevel of chan_misdn, at the moment, level={1,2}"),
2007         AST_CLI_DEFINE(handle_cli_misdn_set_debug,         "Set Debuglevel of chan_misdn"),
2008         AST_CLI_DEFINE(handle_cli_misdn_set_tics,          "???"),
2009         AST_CLI_DEFINE(handle_cli_misdn_toggle_echocancel, "Toggle EchoCancel on mISDN Channel"),
2010 };
2011
2012 /*! \brief Updates caller ID information from config */
2013 static int update_config(struct chan_list *ch, int orig) 
2014 {
2015         struct ast_channel *ast;
2016         struct misdn_bchannel *bc;
2017         int port, hdlc = 0;
2018         int pres, screen;
2019
2020         if (!ch) {
2021                 ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
2022                 return -1;
2023         }
2024
2025         ast = ch->ast;
2026         bc = ch->bc;
2027         if (! ast || ! bc) {
2028                 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
2029                 return -1;
2030         }
2031
2032         port = bc->port;
2033
2034         chan_misdn_log(7, port, "update_config: Getting Config\n");
2035
2036         misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
2037         
2038         if (hdlc) {
2039                 switch (bc->capability) {
2040                 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
2041                 case INFO_CAPABILITY_DIGITAL_RESTRICTED:
2042                         chan_misdn_log(1, bc->port, " --> CONF HDLC\n");
2043                         bc->hdlc = 1;
2044                         break;
2045                 }
2046         }
2047
2048
2049         misdn_cfg_get(port, MISDN_CFG_PRES, &pres, sizeof(pres));
2050         misdn_cfg_get(port, MISDN_CFG_SCREEN, &screen, sizeof(screen));
2051         chan_misdn_log(2, port, " --> pres: %d screen: %d\n", pres, screen);
2052                 
2053         if (pres < 0 || screen < 0) {
2054                 chan_misdn_log(2, port, " --> pres: %x\n", ast->cid.cid_pres);
2055                         
2056                 switch (ast->cid.cid_pres & 0x60) {
2057                 case AST_PRES_RESTRICTED:
2058                         bc->pres = 1;
2059                         chan_misdn_log(2, port, " --> PRES: Restricted (1)\n");
2060                         break;
2061                 case AST_PRES_UNAVAILABLE:
2062                         bc->pres = 2;
2063                         chan_misdn_log(2, port, " --> PRES: Unavailable (2)\n");
2064                         break;
2065                 default:
2066                         bc->pres = 0;
2067                         chan_misdn_log(2, port, " --> PRES: Allowed (0)\n");
2068                         break;
2069                 }
2070
2071                 switch (ast->cid.cid_pres & 0x3) {
2072                 default:
2073                 case AST_PRES_USER_NUMBER_UNSCREENED:
2074                         bc->screen = 0;
2075                         chan_misdn_log(2, port, " --> SCREEN: Unscreened (0)\n");
2076                         break;
2077                 case AST_PRES_USER_NUMBER_PASSED_SCREEN:
2078                         bc->screen = 1;
2079                         chan_misdn_log(2, port, " --> SCREEN: Passed Screen (1)\n");
2080                         break;
2081                 case AST_PRES_USER_NUMBER_FAILED_SCREEN:
2082                         bc->screen = 2;
2083                         chan_misdn_log(2, port, " --> SCREEN: Failed Screen (2)\n");
2084                         break;
2085                 case AST_PRES_NETWORK_NUMBER:
2086                         bc->screen = 3;
2087                         chan_misdn_log(2, port, " --> SCREEN: Network Nr. (3)\n");
2088                         break;
2089                 }
2090         } else {
2091                 bc->screen = screen;
2092                 bc->pres = pres;
2093         }
2094
2095         return 0;
2096 }
2097
2098
2099 static void config_jitterbuffer(struct chan_list *ch)
2100 {
2101         struct misdn_bchannel *bc = ch->bc;
2102         int len = ch->jb_len, threshold = ch->jb_upper_threshold;
2103         
2104         chan_misdn_log(5, bc->port, "config_jb: Called\n");
2105         
2106         if (! len) {
2107                 chan_misdn_log(1, bc->port, "config_jb: Deactivating Jitterbuffer\n");
2108                 bc->nojitter=1;
2109         } else {
2110                 if (len <= 100 || len > 8000) {
2111                         chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
2112                         len = 1000;
2113                 }
2114
2115                 if (threshold > len) {
2116                         chan_misdn_log(0, bc->port, "config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
2117                 }
2118
2119                 if ( ch->jb) {
2120                         cb_log(0, bc->port, "config_jb: We've got a Jitterbuffer Already on this port.\n");
2121                         misdn_jb_destroy(ch->jb);
2122                         ch->jb = NULL;
2123                 }
2124
2125                 ch->jb = misdn_jb_init(len, threshold);
2126
2127                 if (!ch->jb) {
2128                         bc->nojitter = 1;
2129                 }
2130         }
2131 }
2132
2133
2134 void debug_numplan(int port, int numplan, char *type)
2135 {
2136         switch (numplan) {
2137         case NUMPLAN_INTERNATIONAL:
2138                 chan_misdn_log(2, port, " --> %s: International\n", type);
2139                 break;
2140         case NUMPLAN_NATIONAL:
2141                 chan_misdn_log(2, port, " --> %s: National\n", type);
2142                 break;
2143         case NUMPLAN_SUBSCRIBER:
2144                 chan_misdn_log(2, port, " --> %s: Subscriber\n", type);
2145                 break;
2146         case NUMPLAN_UNKNOWN:
2147                 chan_misdn_log(2, port, " --> %s: Unknown\n", type);
2148                 break;
2149                 /* Maybe we should cut off the prefix if present ? */
2150         default:
2151                 chan_misdn_log(0, port, " --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
2152                 break;
2153         }
2154 }
2155
2156
2157 #ifdef MISDN_1_2
2158 static int update_pipeline_config(struct misdn_bchannel *bc)
2159 {
2160         int ec;
2161
2162         misdn_cfg_get(bc->port, MISDN_CFG_PIPELINE, bc->pipeline, sizeof(bc->pipeline));
2163
2164         if (*bc->pipeline) {
2165                 return 0;
2166         }
2167
2168         misdn_cfg_get(bc->port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(ec));
2169         if (ec == 1) {
2170                 ast_copy_string(bc->pipeline, "mg2ec", sizeof(bc->pipeline));
2171         } else if (ec > 1) {
2172                 snprintf(bc->pipeline, sizeof(bc->pipeline), "mg2ec(deftaps=%d)", ec);
2173         }
2174
2175         return 0;
2176 }
2177 #else
2178 static int update_ec_config(struct misdn_bchannel *bc)
2179 {
2180         int ec;
2181         int port = bc->port;
2182
2183         misdn_cfg_get(port, MISDN_CFG_ECHOCANCEL, &ec, sizeof(ec));
2184
2185         if (ec == 1) {
2186                 bc->ec_enable = 1;
2187         } else if (ec > 1) {
2188                 bc->ec_enable = 1;
2189                 bc->ec_deftaps = ec;
2190         }
2191
2192         return 0;
2193 }
2194 #endif
2195
2196
2197 static int read_config(struct chan_list *ch, int orig)
2198 {
2199         struct ast_channel *ast;
2200         struct misdn_bchannel *bc;
2201         int port;
2202         int hdlc = 0;
2203         char lang[BUFFERSIZE + 1];
2204         char faxdetect[BUFFERSIZE + 1];
2205         char buf[256];
2206         char buf2[256];
2207         ast_group_t pg;
2208         ast_group_t cg;
2209
2210         if (!ch) {
2211                 ast_log(LOG_WARNING, "Cannot configure without chanlist\n");
2212                 return -1;
2213         }
2214
2215         ast = ch->ast;
2216         bc = ch->bc;
2217         if (! ast || ! bc) {
2218                 ast_log(LOG_WARNING, "Cannot configure without ast || bc\n");
2219                 return -1;
2220         }
2221         
2222         port = bc->port;
2223         chan_misdn_log(1, port, "read_config: Getting Config\n");
2224
2225         misdn_cfg_get(port, MISDN_CFG_LANGUAGE, lang, sizeof(lang));
2226         ast_string_field_set(ast, language, lang);
2227
2228         misdn_cfg_get(port, MISDN_CFG_MUSICCLASS, ch->mohinterpret, sizeof(ch->mohinterpret));
2229
2230         misdn_cfg_get(port, MISDN_CFG_TXGAIN, &bc->txgain, sizeof(bc->txgain));
2231         misdn_cfg_get(port, MISDN_CFG_RXGAIN, &bc->rxgain, sizeof(bc->rxgain));
2232
2233         misdn_cfg_get(port, MISDN_CFG_INCOMING_EARLY_AUDIO, &ch->incoming_early_audio, sizeof(ch->incoming_early_audio));
2234
2235         misdn_cfg_get(port, MISDN_CFG_SENDDTMF, &bc->send_dtmf, sizeof(bc->send_dtmf));
2236         
2237         misdn_cfg_get(port, MISDN_CFG_ASTDTMF, &ch->ast_dsp, sizeof(int));
2238
2239         if (ch->ast_dsp) {
2240                 ch->ignore_dtmf = 1;
2241         }
2242
2243         misdn_cfg_get(port, MISDN_CFG_NEED_MORE_INFOS, &bc->need_more_infos, sizeof(bc->need_more_infos));
2244         misdn_cfg_get(port, MISDN_CFG_NTTIMEOUT, &ch->nttimeout, sizeof(ch->nttimeout));
2245
2246         misdn_cfg_get(port, MISDN_CFG_NOAUTORESPOND_ON_SETUP, &ch->noautorespond_on_setup, sizeof(ch->noautorespond_on_setup));
2247
2248         misdn_cfg_get(port, MISDN_CFG_FAR_ALERTING, &ch->far_alerting, sizeof(ch->far_alerting));
2249
2250         misdn_cfg_get(port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, sizeof(ch->allowed_bearers));
2251
2252         misdn_cfg_get(port, MISDN_CFG_FAXDETECT, faxdetect, sizeof(faxdetect));
2253
2254         misdn_cfg_get(port, MISDN_CFG_HDLC, &hdlc, sizeof(hdlc));
2255
2256         if (hdlc) {
2257                 switch (bc->capability) {
2258                 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED:
2259                 case INFO_CAPABILITY_DIGITAL_RESTRICTED:
2260                         chan_misdn_log(1, bc->port, " --> CONF HDLC\n");
2261                         bc->hdlc = 1;
2262                         break;
2263                 }
2264                 
2265         }
2266         /*Initialize new Jitterbuffer*/
2267         misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER, &ch->jb_len, sizeof(ch->jb_len));
2268         misdn_cfg_get(port, MISDN_CFG_JITTERBUFFER_UPPER_THRESHOLD, &ch->jb_upper_threshold, sizeof(ch->jb_upper_threshold));
2269
2270         config_jitterbuffer(ch);
2271
2272         misdn_cfg_get(bc->port, MISDN_CFG_CONTEXT, ch->context, sizeof(ch->context));
2273
2274         ast_copy_string(ast->context, ch->context, sizeof(ast->context));
2275
2276 #ifdef MISDN_1_2
2277         update_pipeline_config(bc);
2278 #else
2279         update_ec_config(bc);
2280 #endif
2281
2282         misdn_cfg_get(bc->port, MISDN_CFG_EARLY_BCONNECT, &bc->early_bconnect, sizeof(bc->early_bconnect));
2283
2284         misdn_cfg_get(port, MISDN_CFG_PICKUPGROUP, &pg, sizeof(pg));
2285         misdn_cfg_get(port, MISDN_CFG_CALLGROUP, &cg, sizeof(cg));
2286
2287         chan_misdn_log(5, port, " --> * CallGrp:%s PickupGrp:%s\n", ast_print_group(buf, sizeof(buf), cg), ast_print_group(buf2, sizeof(buf2), pg));
2288         ast->pickupgroup = pg;
2289         ast->callgroup = cg;
2290         
2291         if (orig == ORG_AST) {
2292                 char callerid[BUFFERSIZE + 1];
2293
2294                 /* ORIGINATOR Asterisk (outgoing call) */
2295
2296                 misdn_cfg_get(port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(bc->te_choose_channel));
2297
2298                 if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) {
2299                         ch->faxdetect = strstr(faxdetect, "nojump") ? 2 : 1;
2300                 }
2301
2302                 misdn_cfg_get(port, MISDN_CFG_CALLERID, callerid, sizeof(callerid));
2303                 if (!ast_strlen_zero(callerid)) {
2304                         chan_misdn_log(1, port, " --> * Setting Cid to %s\n", callerid);
2305                         ast_copy_string(bc->oad, callerid, sizeof(bc->oad));
2306                 }
2307
2308                 misdn_cfg_get(port, MISDN_CFG_DIALPLAN, &bc->dnumplan, sizeof(bc->dnumplan));
2309                 misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &bc->onumplan, sizeof(bc->onumplan));
2310                 misdn_cfg_get(port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(bc->cpnnumplan));
2311                 debug_numplan(port, bc->dnumplan, "TON");
2312                 debug_numplan(port, bc->onumplan, "LTON");
2313                 debug_numplan(port, bc->cpnnumplan, "CTON");
2314
2315                 ch->overlap_dial = 0;
2316         } else {
2317                 /* ORIGINATOR MISDN (incoming call) */
2318                 char prefix[BUFFERSIZE + 1] = "";
2319
2320                 if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) {
2321                         ch->faxdetect = (strstr(faxdetect, "nojump")) ? 2 : 1;
2322                 }
2323
2324                 misdn_cfg_get(port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(bc->cpnnumplan));
2325                 debug_numplan(port, bc->cpnnumplan, "CTON");
2326
2327                 switch (bc->onumplan) {
2328                 case NUMPLAN_INTERNATIONAL:
2329                         misdn_cfg_get(bc->port, MISDN_CFG_INTERNATPREFIX, prefix, sizeof(prefix));
2330                         break;
2331
2332                 case NUMPLAN_NATIONAL:
2333                         misdn_cfg_get(bc->port, MISDN_CFG_NATPREFIX, prefix, sizeof(prefix));
2334                         break;
2335                 default:
2336                         break;
2337                 }
2338
2339                 ast_copy_string(buf, bc->oad, sizeof(buf));
2340                 snprintf(bc->oad, sizeof(bc->oad), "%s%s", prefix, buf);
2341
2342                 if (!ast_strlen_zero(bc->dad)) {
2343                         ast_copy_string(bc->orig_dad, bc->dad, sizeof(bc->orig_dad));
2344                 }
2345
2346                 if (ast_strlen_zero(bc->dad) && !ast_strlen_zero(bc->keypad)) {
2347                         ast_copy_string(bc->dad, bc->keypad, sizeof(bc->dad));
2348                 }
2349
2350                 prefix[0] = 0;
2351
2352                 switch (bc->dnumplan) {
2353                 case NUMPLAN_INTERNATIONAL:
2354                         misdn_cfg_get(bc->port, MISDN_CFG_INTERNATPREFIX, prefix, sizeof(prefix));
2355                         break;
2356                 case NUMPLAN_NATIONAL:
2357                         misdn_cfg_get(bc->port, MISDN_CFG_NATPREFIX, prefix, sizeof(prefix));
2358                         break;
2359                 default:
2360                         break;
2361                 }
2362
2363                 ast_copy_string(buf, bc->dad, sizeof(buf));
2364                 snprintf(bc->dad, sizeof(bc->dad), "%s%s", prefix, buf);
2365
2366                 if (strcmp(bc->dad, ast->exten)) {
2367                         ast_copy_string(ast->exten, bc->dad, sizeof(ast->exten));
2368                 }
2369
2370                 ast_set_callerid(ast, bc->oad, NULL, bc->oad);
2371
2372                 if ( !ast_strlen_zero(bc->rad) ) {
2373                         if (ast->cid.cid_rdnis) {
2374                                 ast_free(ast->cid.cid_rdnis);
2375                         }
2376                         ast->cid.cid_rdnis = ast_strdup(bc->rad);
2377                 }
2378         
2379                 misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial));
2380                 ast_mutex_init(&ch->overlap_tv_lock);
2381         } /* ORIG MISDN END */
2382
2383         ch->overlap_dial_task = -1;
2384         
2385         if (ch->faxdetect  || ch->ast_dsp) {
2386                 misdn_cfg_get(port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout));
2387                 if (!ch->dsp) {
2388                         ch->dsp = ast_dsp_new();
2389                 }
2390                 if (ch->dsp) {
2391                         ast_dsp_set_features(ch->dsp, DSP_FEATURE_DIGIT_DETECT | (ch->faxdetect ? DSP_FEATURE_FAX_DETECT : 0));
2392                 }
2393                 if (!ch->trans) {
2394                         ch->trans = ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW);
2395                 }
2396         }
2397
2398         /* AOCD initialization */
2399         bc->AOCDtype = Fac_None;
2400
2401         return 0;
2402 }
2403
2404
2405 /*****************************/
2406 /*** AST Indications Start ***/
2407 /*****************************/
2408
2409 static int misdn_call(struct ast_channel *ast, char *dest, int timeout)
2410 {
2411         int port = 0;
2412         int r;
2413         int exceed;
2414         int bridging;
2415         struct chan_list *ch = MISDN_ASTERISK_TECH_PVT(ast);
2416         struct misdn_bchannel *newbc;
2417         char *dest_cp = ast_strdupa(dest);
2418         AST_DECLARE_APP_ARGS(args,
2419                 AST_APP_ARG(type);
2420                 AST_APP_ARG(ext);
2421                 AST_APP_ARG(opts);
2422         );
2423
2424         AST_NONSTANDARD_APP_ARGS(args, dest_cp, '/');
2425
2426         if (ast_strlen_zero(args.ext)) {
2427                 chan_misdn_log(0, 0, "misdn_call: No Extension given!\n");
2428                 return -1;
2429         }
2430
2431         if (!ast) {
2432                 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
2433                 return -1;
2434         }
2435
2436         if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest) {
2437                 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
2438                 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
2439                 ast_setstate(ast, AST_STATE_DOWN);
2440                 return -1;
2441         }
2442
2443         if (!ch) {
2444                 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
2445                 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
2446                 ast_setstate(ast, AST_STATE_DOWN);
2447                 return -1;
2448         }
2449         
2450         newbc = ch->bc;
2451         
2452         if (!newbc) {
2453                 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
2454                 ast->hangupcause = AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
2455                 ast_setstate(ast, AST_STATE_DOWN);
2456                 return -1;
2457         }
2458         
2459         port = newbc->port;
2460
2461         if ((exceed = add_out_calls(port))) {
2462                 char tmp[16];
2463                 snprintf(tmp, sizeof(tmp), "%d", exceed);
2464                 pbx_builtin_setvar_helper(ast, "MAX_OVERFLOW", tmp);
2465                 return -1;
2466         }
2467         
2468         chan_misdn_log(1, port, "* CALL: %s\n", dest);
2469         
2470         chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n", ast->exten, ast->name, ast->context);
2471         
2472         chan_misdn_log(3, port, " --> * adding2newbc ext %s\n", ast->exten);
2473         if (ast->exten) {
2474                 ast_copy_string(ast->exten, args.ext, sizeof(ast->exten));
2475                 ast_copy_string(newbc->dad, args.ext, sizeof(newbc->dad));
2476         }
2477
2478         ast_copy_string(newbc->rad, S_OR(ast->cid.cid_rdnis, ""), sizeof(newbc->rad));
2479
2480         chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n", ast->cid.cid_num);
2481         if (ast_strlen_zero(newbc->oad) && !ast_strlen_zero(ast->cid.cid_num)) {
2482                 ast_copy_string(newbc->oad, ast->cid.cid_num, sizeof(newbc->oad));
2483         }
2484
2485         newbc->capability = ast->transfercapability;
2486         pbx_builtin_setvar_helper(ast, "TRANSFERCAPABILITY", ast_transfercapability2str(newbc->capability));
2487         if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) {
2488                 chan_misdn_log(2, port, " --> * Call with flag Digital\n");
2489         }
2490
2491         /* update screening and presentation */ 
2492         update_config(ch, ORG_AST);
2493                 
2494         /* fill in some ies from channel vary */
2495         import_ch(ast, newbc, ch);
2496
2497         /* Finally The Options Override Everything */
2498         if (!ast_strlen_zero(args.opts)) {
2499                 misdn_set_opt_exec(ast, args.opts);
2500         } else {
2501                 chan_misdn_log(2, port, "NO OPTS GIVEN\n");
2502         }
2503
2504         /*check for bridging*/
2505         misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging));
2506         if (bridging && ch->other_ch) {
2507 #ifdef MISDN_1_2
2508                 chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n");
2509                 *ch->bc->pipeline = 0;
2510                 *ch->other_ch->bc->pipeline = 0;
2511 #else
2512                 chan_misdn_log(1, port, "Disabling EC on both Sides\n");
2513                 ch->bc->ec_enable = 0;
2514                 ch->other_ch->bc->ec_enable = 0;
2515 #endif
2516         }
2517
2518         r = misdn_lib_send_event(newbc, EVENT_SETUP);
2519
2520         /** we should have l3id after sending setup **/
2521         ch->l3id = newbc->l3_id;
2522
2523         if (r == -ENOCHAN ) {
2524                 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
2525                 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n", newbc ? newbc->pid : -1);
2526                 ast->hangupcause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
2527                 ast_setstate(ast, AST_STATE_DOWN);
2528                 return -1;
2529         }
2530
2531         chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n", newbc ? newbc->pid : 1);
2532
2533         ast_setstate(ast, AST_STATE_DIALING);
2534         ast->hangupcause = AST_CAUSE_NORMAL_CLEARING;
2535
2536         if (newbc->nt) {
2537                 stop_bc_tones(ch);
2538         }
2539
2540         ch->state = MISDN_CALLING;
2541         
2542         return 0; 
2543 }
2544
2545
2546 static int misdn_answer(struct ast_channel *ast)
2547 {
2548         struct chan_list *p;
2549         const char *tmp;
2550
2551         if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
2552                 return -1;
2553         }
2554         
2555         chan_misdn_log(1, p ? (p->bc ? p->bc->port : 0) : 0, "* ANSWER:\n");
2556         
2557         if (!p) {
2558                 ast_log(LOG_WARNING, " --> Channel not connected ??\n");
2559                 ast_queue_hangup_with_cause(ast, AST_CAUSE_NETWORK_OUT_OF_ORDER);
2560         }
2561
2562         if (!p->bc) {
2563                 chan_misdn_log(1, 0, " --> Got Answer, but there is no bc obj ??\n");
2564
2565                 ast_queue_hangup_with_cause(ast, AST_CAUSE_PROTOCOL_ERROR);
2566         }
2567
2568         ast_channel_lock(ast);
2569         tmp = pbx_builtin_getvar_helper(ast, "CRYPT_KEY");
2570         if (!ast_strlen_zero(tmp)) {
2571                 chan_misdn_log(1, p->bc->port, " --> Connection will be BF crypted\n");
2572                 ast_copy_string(p->bc->crypt_key, tmp, sizeof(p->bc->crypt_key));
2573         } else {
2574                 chan_misdn_log(3, p->bc->port, " --> Connection is without BF encryption\n");
2575         }
2576
2577         tmp = pbx_builtin_getvar_helper(ast, "MISDN_DIGITAL_TRANS");
2578         if (!ast_strlen_zero(tmp) && ast_true(tmp)) {
2579                 chan_misdn_log(1, p->bc->port, " --> Connection is transparent digital\n");
2580                 p->bc->nodsp = 1;
2581                 p->bc->hdlc = 0;
2582                 p->bc->nojitter = 1;
2583         }
2584         ast_channel_unlock(ast);
2585
2586         p->state = MISDN_CONNECTED;
2587         stop_indicate(p);
2588
2589         if ( ast_strlen_zero(p->bc->cad) ) {
2590                 chan_misdn_log(2, p->bc->port, " --> empty cad using dad\n");
2591                 ast_copy_string(p->bc->cad, p->bc->dad, sizeof(p->bc->cad));
2592         }
2593
2594         misdn_lib_send_event(p->bc, EVENT_CONNECT);
2595         start_bc_tones(p);
2596
2597         return 0;
2598 }
2599
2600 static int misdn_digit_begin(struct ast_channel *chan, char digit)
2601 {
2602         /* XXX Modify this callback to support Asterisk controlling the length of DTMF */
2603         return 0;
2604 }
2605
2606 static int misdn_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
2607 {
2608         struct chan_list *p;
2609         struct misdn_bchannel *bc;
2610         char buf[2] = { digit, 0 };
2611
2612         if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
2613                 return -1;
2614         }
2615
2616         bc = p->bc;
2617         chan_misdn_log(1, bc ? bc->port : 0, "* IND : Digit %c\n", digit);
2618         
2619         if (!bc) {
2620                 ast_log(LOG_WARNING, " --> !! Got Digit Event without having bchannel Object\n");
2621                 return -1;
2622         }
2623         
2624         switch (p->state ) {
2625         case MISDN_CALLING:
2626                 if (strlen(bc->infos_pending) < sizeof(bc->infos_pending) - 1) {
2627                         strncat(bc->infos_pending, buf, sizeof(bc->infos_pending) - strlen(bc->infos_pending) - 1);
2628                 }
2629                 break;
2630         case MISDN_CALLING_ACKNOWLEDGE:
2631                 ast_copy_string(bc->info_dad, buf, sizeof(bc->info_dad));
2632                 if (strlen(bc->dad) < sizeof(bc->dad) - 1) {
2633                         strncat(bc->dad, buf, sizeof(bc->dad) - strlen(bc->dad) - 1);
2634                 }
2635                 ast_copy_string(p->ast->exten, bc->dad, sizeof(p->ast->exten));
2636                 misdn_lib_send_event(bc, EVENT_INFORMATION);
2637                 break;
2638         default:
2639                 /* Do not send Digits in CONNECTED State, when
2640                  * the other side is too mISDN. */
2641                 if (p->other_ch) {
2642                         return 0;
2643                 }
2644
2645                 if (bc->send_dtmf) {
2646                         send_digit_to_chan(p, digit);
2647                 }
2648                 break;
2649         }
2650
2651         return 0;
2652 }
2653
2654
2655 static int misdn_fixup(struct ast_channel *oldast, struct ast_channel *ast)
2656 {
2657         struct chan_list *p;
2658
2659         if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
2660                 return -1;
2661         }
2662
2663         chan_misdn_log(1, p->bc ? p->bc->port : 0, "* IND: Got Fixup State:%s L3id:%x\n", misdn_get_ch_state(p), p->l3id);
2664
2665         p->ast = ast;
2666
2667         return 0;
2668 }
2669
2670
2671
2672 static int misdn_indication(struct ast_channel *ast, int cond, const void *data, size_t datalen)
2673 {
2674         struct chan_list *p;
2675
2676         if (!ast || ! (p=MISDN_ASTERISK_TECH_PVT(ast))) {
2677                 ast_log(LOG_WARNING, "Returned -1 in misdn_indication\n");
2678                 return -1;
2679         }
2680         
2681         if (!p->bc ) {
2682                 chan_misdn_log(1, 0, "* IND : Indication from %s\n", ast->exten);
2683                 ast_log(LOG_WARNING, "Private Pointer but no bc ?\n");
2684                 return -1;
2685         }
2686         
2687         chan_misdn_log(5, p->bc->port, "* IND : Indication [%d] from %s\n", cond, ast->exten);
2688         
2689         switch (cond) {
2690         case AST_CONTROL_BUSY:
2691                 chan_misdn_log(1, p->bc->port, "* IND :\tbusy pid:%d\n", p->bc ? p->bc->pid : -1);
2692                 ast_setstate(ast, AST_STATE_BUSY);
2693
2694                 p->bc->out_cause = AST_CAUSE_USER_BUSY;
2695                 if (p->state != MISDN_CONNECTED) {
2696                         start_bc_tones(p);
2697                         misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
2698                 } else {
2699                         chan_misdn_log(-1, p->bc->port, " --> !! Got Busy in Connected State !?! ast:%s\n", ast->name);
2700                 }
2701                 return -1;
2702         case AST_CONTROL_RING:
2703                 chan_misdn_log(1, p->bc->port, "* IND :\tring pid:%d\n", p->bc ? p->bc->pid : -1);
2704                 return -1;
2705         case AST_CONTROL_RINGING:
2706                 chan_misdn_log(1, p->bc->port, "* IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1);
2707                 switch (p->state) {
2708                 case MISDN_ALERTING:
2709                         chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoring it\n", p->bc ? p->bc->pid : -1);
2710                         break;
2711                 case MISDN_CONNECTED:
2712                         chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n", p->bc ? p->bc->pid : -1);
2713                         return -1;
2714                 default:
2715                         p->state = MISDN_ALERTING;
2716                         chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc ? p->bc->pid : -1);
2717                         misdn_lib_send_event( p->bc, EVENT_ALERTING);
2718
2719                         if (p->other_ch && p->other_ch->bc) {
2720                                 if (misdn_inband_avail(p->other_ch->bc)) {
2721                                         chan_misdn_log(2, p->bc->port, " --> other End is mISDN and has inband info available\n");
2722                                         break;
2723                                 }
2724
2725                                 if (!p->other_ch->bc->nt) {
2726                                         chan_misdn_log(2, p->bc->port, " --> other End is mISDN TE so it has inband info for sure (?)\n");
2727                                         break;
2728                                 }
2729                         }
2730
2731                         chan_misdn_log(3, p->bc->port, " --> * SEND: State Ring pid:%d\n", p->bc ? p->bc->pid : -1);
2732                         ast_setstate(ast, AST_STATE_RING);
2733
2734                         if (!p->bc->nt && (p->originator == ORG_MISDN) && !p->incoming_early_audio) {
2735                                 chan_misdn_log(2, p->bc->port, " --> incoming_early_audio off\n");
2736                         } else {
2737                                 return -1;
2738                         }
2739                 }
2740                 break;
2741         case AST_CONTROL_ANSWER:
2742                 chan_misdn_log(1, p->bc->port, " --> * IND :\tanswer pid:%d\n", p->bc ? p->bc->pid : -1);
2743                 start_bc_tones(p);
2744                 break;
2745         case AST_CONTROL_TAKEOFFHOOK:
2746                 chan_misdn_log(1, p->bc->port, " --> *\ttakeoffhook pid:%d\n", p->bc ? p->bc->pid : -1);
2747                 return -1;
2748         case AST_CONTROL_OFFHOOK:
2749                 chan_misdn_log(1, p->bc->port, " --> *\toffhook pid:%d\n", p->bc ? p->bc->pid : -1);
2750                 return -1;
2751         case AST_CONTROL_FLASH:
2752                 chan_misdn_log(1, p->bc->port, " --> *\tflash pid:%d\n", p->bc ? p->bc->pid : -1);
2753                 break;
2754         case AST_CONTROL_PROGRESS:
2755                 chan_misdn_log(1, p->bc->port, " --> * IND :\tprogress pid:%d\n", p->bc ? p->bc->pid : -1);
2756                 misdn_lib_send_event( p->bc, EVENT_PROGRESS);
2757                 break;
2758         case AST_CONTROL_PROCEEDING:
2759                 chan_misdn_log(1, p->bc->port, " --> * IND :\tproceeding pid:%d\n", p->bc ? p->bc->pid : -1);
2760                 misdn_lib_send_event( p->bc, EVENT_PROCEEDING);
2761                 break;
2762         case AST_CONTROL_CONGESTION:
2763                 chan_misdn_log(1, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc ? p->bc->pid : -1);
2764
2765                 p->bc->out_cause = AST_CAUSE_SWITCH_CONGESTION;
2766                 start_bc_tones(p);
2767                 misdn_lib_send_event( p->bc, EVENT_DISCONNECT);
2768
2769                 if (p->bc->nt) {
2770                         hanguptone_indicate(p);
2771                 }
2772                 break;
2773         case -1 :
2774                 chan_misdn_log(1, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc ? p->bc->pid : -1);
2775
2776                 stop_indicate(p);
2777
2778                 if (p->state == MISDN_CONNECTED) {
2779                         start_bc_tones(p);
2780                 }
2781                 break;
2782         case AST_CONTROL_HOLD:
2783                 ast_moh_start(ast, data, p->mohinterpret); 
2784                 chan_misdn_log(1, p->bc->port, " --> *\tHOLD pid:%d\n", p->bc ? p->bc->pid : -1);
2785                 break;
2786         case AST_CONTROL_UNHOLD:
2787                 ast_moh_stop(ast);
2788                 chan_misdn_log(1, p->bc->port, " --> *\tUNHOLD pid:%d\n", p->bc ? p->bc->pid : -1);
2789                 break;
2790         default:
2791                 chan_misdn_log(1, p->bc->port, " --> * Unknown Indication:%d pid:%d\n", cond, p->bc ? p->bc->pid : -1);
2792         }
2793   
2794         return 0;
2795 }
2796
2797 static int misdn_hangup(struct ast_channel *ast)
2798 {
2799         struct chan_list *p;
2800         struct misdn_bchannel *bc = NULL;
2801         const char *varcause = NULL;
2802
2803         ast_debug(1, "misdn_hangup(%s)\n", ast->name);
2804
2805         if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast))) {
2806                 return -1;
2807         }
2808
2809         if (!p) {
2810                 chan_misdn_log(3, 0, "misdn_hangup called, without chan_list obj.\n");
2811                 return 0 ;
2812         }
2813
2814         bc = p->bc;
2815
2816         if (bc) {
2817                 const char *tmp;
2818                 ast_channel_lock(ast);
2819                 if ((tmp = pbx_builtin_getvar_helper(ast, "MISDN_USERUSER"))) {
2820                         ast_log(LOG_NOTICE, "MISDN_USERUSER: %s\n", tmp);
2821                         strcpy(bc->uu, tmp);
2822                         bc->uulen = strlen(bc->uu);
2823                 }
2824                 ast_channel_unlock(ast);
2825         }
2826
2827         MISDN_ASTERISK_TECH_PVT(ast) = NULL;
2828         p->ast = NULL;
2829
2830         if (ast->_state == AST_STATE_RESERVED || 
2831                 p->state == MISDN_NOTHING || 
2832                 p->state == MISDN_HOLDED || 
2833                 p->state == MISDN_HOLD_DISCONNECT ) {
2834
2835                 CLEAN_CH:
2836                 /* between request and call */
2837                 ast_debug(1, "State Reserved (or nothing) => chanIsAvail\n");
2838                 MISDN_ASTERISK_TECH_PVT(ast) = NULL;
2839         
2840                 ast_mutex_lock(&release_lock);
2841                 cl_dequeue_chan(&cl_te, p);
2842                 close(p->pipe[0]);
2843                 close(p->pipe[1]);
2844                 ast_free(p);
2845                 ast_mutex_unlock(&release_lock);
2846
2847                 if (bc) {
2848                         misdn_lib_release(bc);
2849                 }
2850
2851                 return 0;
2852         }
2853
2854         if (!bc) {
2855                 ast_log(LOG_WARNING, "Hangup with private but no bc ? state:%s l3id:%x\n", misdn_get_ch_state(p), p->l3id);
2856                 goto CLEAN_CH;
2857         }
2858
2859
2860         p->need_hangup = 0;
2861         p->need_queue_hangup = 0;
2862         p->need_busy = 0;
2863
2864
2865         if (!p->bc->nt) {
2866                 stop_bc_tones(p);
2867         }
2868
2869         bc->out_cause = ast->hangupcause ? ast->hangupcause : AST_CAUSE_NORMAL_CLEARING;
2870
2871         ast_channel_lock(ast);
2872         if ((varcause = pbx_builtin_getvar_helper(ast, "HANGUPCAUSE")) ||
2873                 (varcause = pbx_builtin_getvar_helper(ast, "PRI_CAUSE"))) {
2874                 int tmpcause = atoi(varcause);
2875                 bc->out_cause = tmpcause ? tmpcause : AST_CAUSE_NORMAL_CLEARING;
2876         }
2877         ast_channel_unlock(ast);
2878
2879         chan_misdn_log(1, bc->port, "* IND : HANGUP\tpid:%d ctx:%s dad:%s oad:%s State:%s\n", p->bc ? p->bc->pid : -1, ast->context, ast->exten, ast->cid.cid_num, misdn_get_ch_state(p));
2880         chan_misdn_log(3, bc->port, " --> l3id:%x\n", p->l3id);
2881         chan_misdn_log(3, bc->port, " --> cause:%d\n", bc->cause);
2882         chan_misdn_log(2, bc->port, " --> out_cause:%d\n", bc->out_cause);
2883         chan_misdn_log(2, bc->port, " --> state:%s\n", misdn_get_ch_state(p));
2884
2885         switch (p->state) {
2886         case MISDN_INCOMING_SETUP:
2887         case MISDN_CALLING:
2888                 p->state = MISDN_CLEANING;
2889                 /* This is the only place in misdn_hangup, where we 
2890                  * can call release_chan, else it might create lot's of trouble
2891                  * */
2892                 ast_log(LOG_NOTICE, "release channel, in CALLING/INCOMING_SETUP state.. no other events happened\n");
2893                 release_chan(bc);
2894                 misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
2895                 break;
2896         case MISDN_HOLDED:
2897         case MISDN_DIALING:
2898                 start_bc_tones(p);
2899                 hanguptone_indicate(p);
2900
2901                 p->state = MISDN_CLEANING;
2902                 if (bc->need_disconnect) {
2903                         misdn_lib_send_event(bc, EVENT_DISCONNECT);
2904                 }
2905                 break;
2906         case MISDN_CALLING_ACKNOWLEDGE:
2907                 start_bc_tones(p);
2908                 hanguptone_indicate(p);
2909
2910                 if (bc->need_disconnect) {
2911                         misdn_lib_send_event(bc, EVENT_DISCONNECT);
2912                 }
2913                 break;
2914
2915         case MISDN_ALERTING:
2916         case MISDN_PROGRESS:
2917         case MISDN_PROCEEDING:
2918                 if (p->originator != ORG_AST) {
2919                         hanguptone_indicate(p);
2920                 }
2921
2922                 /*p->state=MISDN_CLEANING;*/
2923                 if (bc->need_disconnect) {
2924                         misdn_lib_send_event(bc, EVENT_DISCONNECT);
2925                 }
2926                 break;
2927         case MISDN_CONNECTED:
2928         case MISDN_PRECONNECTED:
2929                 /*  Alerting or Disconnect */
2930                 if (p->bc->nt) {
2931                         start_bc_tones(p);
2932                         hanguptone_indicate(p);
2933                         p->bc->progress_indicator = INFO_PI_INBAND_AVAILABLE;
2934                 }
2935                 if (bc->need_disconnect) {
2936                         misdn_lib_send_event(bc, EVENT_DISCONNECT);
2937                 }
2938
2939                 /*p->state=MISDN_CLEANING;*/
2940                 break;
2941         case MISDN_DISCONNECTED:
2942                 if (bc->need_release) {
2943                         misdn_lib_send_event(bc, EVENT_RELEASE);
2944                 }
2945                 p->state = MISDN_CLEANING; /* MISDN_HUNGUP_FROM_AST; */
2946                 break;
2947
2948         case MISDN_RELEASED:
2949         case MISDN_CLEANING:
2950                 p->state = MISDN_CLEANING;
2951                 break;
2952
2953         case MISDN_BUSY:
2954                 break;
2955
2956         case MISDN_HOLD_DISCONNECT:
2957                 /* need to send release here */
2958                 chan_misdn_log(1, bc->port, " --> cause %d\n", bc->cause);
2959                 chan_misdn_log(1, bc->port, " --> out_cause %d\n", bc->out_cause);
2960
2961                 bc->out_cause = -1;
2962                 if (bc->need_release) {
2963                         misdn_lib_send_event(bc, EVENT_RELEASE);
2964                 }
2965                 p->state = MISDN_CLEANING;
2966                 break;
2967         default:
2968                 if (bc->nt) {
2969                         bc->out_cause = -1;
2970                         if (bc->need_release) {
2971                                 misdn_lib_send_event(bc, EVENT_RELEASE);
2972                         }
2973                         p->state = MISDN_CLEANING; 
2974                 } else {
2975                         if (bc->need_disconnect) {
2976                                 misdn_lib_send_event(bc, EVENT_DISCONNECT);
2977                         }
2978                 }
2979         }
2980
2981         p->state = MISDN_CLEANING;
2982
2983         chan_misdn_log(3, bc->port, " --> Channel: %s hanguped new state:%s\n", ast->name, misdn_get_ch_state(p));
2984
2985         return 0;
2986 }
2987
2988
2989 static struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame)
2990 {
2991         struct ast_frame *f,*f2;
2992  
2993         if (tmp->trans) {
2994                 f2 = ast_translate(tmp->trans, frame, 0);
2995                 f = ast_dsp_process(tmp->ast, tmp->dsp, f2);
2996         } else {
2997                 chan_misdn_log(0, tmp->bc->port, "No T-Path found\n");
2998                 return NULL;
2999         }
3000
3001         if (!f || (f->frametype != AST_FRAME_DTMF))
3002                 return frame;
3003  
3004         ast_debug(1, "Detected inband DTMF digit: %c\n", f->subclass);
3005  
3006         if (tmp->faxdetect && (f->subclass == 'f')) {
3007                 /* Fax tone -- Handle and return NULL */
3008                 if (!tmp->faxhandled) {
3009                         struct ast_channel *ast = tmp->ast;
3010                         tmp->faxhandled++;
3011                         chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name);
3012                         tmp->bc->rxgain = 0;
3013                         isdn_lib_update_rxgain(tmp->bc);
3014                         tmp->bc->txgain = 0;
3015                         isdn_lib_update_txgain(tmp->bc);
3016 #ifdef MISDN_1_2
3017                         *tmp->bc->pipeline = 0;
3018 #else
3019                         tmp->bc->ec_enable = 0;
3020 #endif
3021                         isdn_lib_update_ec(tmp->bc);
3022                         isdn_lib_stop_dtmf(tmp->bc);
3023                         switch (tmp->faxdetect) {
3024                         case 1:
3025                                 if (strcmp(ast->exten, "fax")) {
3026                                         char *context;
3027                                         char context_tmp[BUFFERSIZE];
3028                                         misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp));
3029                                         context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp;
3030                                         if (ast_exists_extension(ast, context, "fax", 1, ast->cid.cid_num)) {
3031                                                 ast_verb(3, "Redirecting %s to fax extension (context:%s)\n", ast->name, context);
3032                                                 /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
3033                                                 pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
3034                                                 if (ast_async_goto(ast, context, "fax", 1)) {
3035                                                         ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context);
3036                                                 }
3037                                         } else {
3038                                                 ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n", context, ast->exten);
3039                                         }
3040                                 } else {
3041                                         ast_debug(1, "Already in a fax extension, not redirecting\n");
3042                                 }
3043                                 break;
3044                         case 2:
3045                                 ast_verb(3, "Not redirecting %s to fax extension, nojump is set.\n", ast->name);
3046                                 break;
3047                         }
3048                 } else {
3049                         ast_debug(1, "Fax already handled\n");
3050                 }
3051         }
3052         
3053         if (tmp->ast_dsp && (f->subclass != 'f')) {
3054                 chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass);
3055         }
3056
3057         return f;
3058 }
3059
3060
3061 static struct ast_frame *misdn_read(struct ast_channel *ast)
3062 {
3063         struct chan_list *tmp;
3064         fd_set rrfs;
3065         struct timeval tv = { 0, 20000 };
3066         int len, t;
3067
3068         if (!ast) {
3069                 chan_misdn_log(1, 0, "misdn_read called without ast\n");
3070                 return NULL;
3071         }
3072         if (!(tmp = MISDN_ASTERISK_TECH_PVT(ast))) {
3073                 chan_misdn_log(1, 0, "misdn_read called without ast->pvt\n");
3074                 return NULL;
3075         }
3076
3077         if (!tmp->bc && !(tmp->state == MISDN_HOLDED)) {
3078                 chan_misdn_log(1, 0, "misdn_read called without bc\n");
3079                 return NULL;
3080         }
3081
3082         FD_ZERO(&rrfs);
3083         FD_SET(tmp->pipe[0], &rrfs);
3084
3085         if (!(t = select(FD_SETSIZE, &rrfs, NULL, NULL, &tv))) {
3086                 chan_misdn_log(3, tmp->bc->port, "read Select Timed out\n");
3087                 len = 160;
3088         }
3089
3090         if (t < 0) {
3091                 chan_misdn_log(-1, tmp->bc->port, "Select Error (err=%s)\n", strerror(errno));
3092                 return NULL;
3093         }
3094
3095         if (FD_ISSET(tmp->pipe[0], &rrfs)) {
3096                 len = read(tmp->pipe[0], tmp->ast_rd_buf, sizeof(tmp->ast_rd_buf));
3097
3098                 if (len <= 0) {
3099                         /* we hangup here, since our pipe is closed */
3100                         chan_misdn_log(2, tmp->bc->port, "misdn_read: Pipe closed, hanging up\n");
3101                         return NULL;
3102                 }
3103
3104         } else {
3105                 return NULL;
3106         }
3107
3108         tmp->frame.frametype = AST_FRAME_VOICE;
3109         tmp->frame.subclass = AST_FORMAT_ALAW;
3110         tmp->frame.datalen = len;
3111         tmp->frame.samples = len;
3112         tmp->frame.mallocd = 0;
3113         tmp->frame.offset = 0;
3114         tmp->frame.delivery = ast_tv(0, 0);
3115         tmp->frame.src = NULL;
3116         tmp->frame.data.ptr = tmp->ast_rd_buf;
3117
3118         if (tmp->faxdetect && !tmp->faxhandled) {
3119                 if (tmp->faxdetect_timeout) {
3120                         if (ast_tvzero(tmp->faxdetect_tv)) {
3121                                 tmp->faxdetect_tv = ast_tvnow();
3122                                 chan_misdn_log(2, tmp->bc->port, "faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout);
3123                                 return process_ast_dsp(tmp, &tmp->frame);
3124                         } else {
3125                                 struct timeval tv_now = ast_tvnow();
3126                                 int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv);
3127                                 if (diff <= (tmp->faxdetect_timeout * 1000)) {
3128                                         chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ...\n");
3129                                         return process_ast_dsp(tmp, &tmp->frame);
3130                                 } else {
3131                                         chan_misdn_log(2, tmp->bc->port, "faxdetect: stopping detection (time ran out) ...\n");
3132                                         tmp->faxdetect = 0;
3133                                         return &tmp->frame;
3134                                 }
3135                         }
3136                 } else {
3137                         chan_misdn_log(5, tmp->bc->port, "faxdetect: detecting ... (no timeout)\n");
3138                         return process_ast_dsp(tmp, &tmp->frame);
3139                 }
3140         } else {
3141                 if (tmp->ast_dsp) {
3142                         return process_ast_dsp(tmp, &tmp->frame);
3143                 } else {
3144                         return &tmp->frame;
3145                 }
3146         }
3147 }
3148
3149
3150 static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
3151 {
3152         struct chan_list *ch;
3153         int i  = 0;
3154         
3155         if (!ast || !(ch = MISDN_ASTERISK_TECH_PVT(ast))) {
3156                 return -1;
3157         }
3158
3159         if (ch->state == MISDN_HOLDED) {
3160                 chan_misdn_log(7, 0, "misdn_write: Returning because holded\n");
3161                 return 0;
3162         }
3163         
3164         if (!ch->bc ) {
3165                 ast_log(LOG_WARNING, "private but no bc\n");
3166                 return -1;
3167         }
3168         
3169         if (ch->notxtone) {
3170                 chan_misdn_log(7, ch->bc->port, "misdn_write: Returning because notxtone\n");
3171                 return 0;