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