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