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