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