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