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