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