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