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