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