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