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