f33d9170a44d3cd3c32b77138f721c973d0ce924
[lcr.git] / chan_lcr.c
1 /*****************************************************************************\
2 **                                                                           **
3 ** Linux Call Router                                                         **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** Asterisk socket client                                                    **
9 **                                                                           **
10 \*****************************************************************************/
11
12 /*
13
14 Registering to LCR:
15
16 To connect, open an LCR socket and send a MESSAGE_HELLO to socket with
17 the application name. This name is unique an can be used for routing calls.
18 Now the channel driver is linked to LCR and can receive and make calls.
19
20
21 Call is initiated by LCR:
22
23 If a call is received from LCR, a MESSAGE_NEWREF is received first.
24 A new chan_call instance is created. The call reference (ref) is given by
25 MESSAGE_NEWREF. The state is CHAN_LCR_STATE_IN_PREPARE.
26 After receiving MESSAGE_SETUP from LCR, the ast_channel instance is created
27 using ast_channel_alloc(1).  The setup information is given to asterisk.
28 The new Asterisk instance pointer (ast) is stored to chan_call structure.
29 The state changes to CHAN_LCR_STATE_IN_SETUP.
30
31
32 Call is initiated by Asterisk:
33
34 If a call is reveiced from Asterisk, a new chan_call instance is created.
35 The new Asterisk instance pointer (ast) is stored to chan_call structure.
36 A MESSASGE_NEWREF is sent to LCR requesting a new call reference (ref).
37 The current call ref is set to 0, the state is CHAN_LCR_STATE_OUT_PREPARE.
38 Further dialing information is queued.
39 After the new callref is received by special MESSAGE_NEWREF reply, new ref
40 is stored in the chan_call structure. 
41 The setup information is sent to LCR using MESSAGE_SETUP.
42 The state changes to CHAN_LCR_STATE_OUT_SETUP.
43
44
45 Call is in process:
46
47 During call process, messages are received and sent.
48 The state changes accordingly.
49 Any message is allowed to be sent to LCR at any time except MESSAGE_RELEASE.
50 If a MESSAGE_OVERLAP is received, further dialing is required.
51 Queued dialing information, if any, is sent to LCR using MESSAGE_DIALING.
52 In this case, the state changes to CHAN_LCR_STATE_OUT_DIALING.
53
54
55 Call is released by LCR:
56
57 A MESSAGE_RELEASE is received with the call reference (ref) to be released.
58 The current ref is set to 0, to indicate released reference.
59 The state changes to CHAN_LCR_STATE_RELEASE.
60 ast_queue_hangup() is called, if asterisk instance (ast) exists, if not,
61 the chan_call instance is destroyed.
62 After lcr_hangup() is called-back by Asterisk, the chan_call instance
63 is destroyed, because the current ref is set to 0 and the state equals
64 CHAN_LCR_STATE_RELEASE.
65 If the ref is 0 and the state is not CHAN_LCR_STATE_RELEASE, see the proceedure
66 "Call is released by Asterisk".
67
68
69 Call is released by Asterisk:
70
71 lcr_hangup() is called-back by Asterisk. If the call reference (ref) is set,
72 a MESSAGE_RELEASE is sent to LCR and the chan_call instance is destroyed.
73 If the ref is 0 and the state is not CHAN_LCR_STATE_RELEASE, the new state is
74 set to CHAN_LCR_STATE_RELEASE.
75 Later, if the MESSAGE_NEWREF reply is received, a MESSAGE_RELEASE is sent to
76 LCR and the chan_call instance is destroyed.
77 If the ref is 0 and the state is CHAN_LCR_STATE_RELEASE, see the proceedure
78 "Call is released by LCR".
79
80 */
81
82 u_char flip_bits[256];
83
84 #warning TODO: bchannel oeffnen und aktivieren (wer macht das?:)
85 #warning reconnect after socket closed, release all calls.
86 #warning debug of call handling
87 #warning ausloesen beim socket-verlust
88
89 #include <stdio.h>
90 #include <stdlib.h>
91 #include <string.h>
92 #include <stdarg.h>
93 #include <errno.h>
94 #include <sys/types.h>
95 #include <time.h>
96 #include <unistd.h>
97 #include <fcntl.h>
98 #include <sys/ioctl.h>
99 #include <sys/socket.h>
100 #include <sys/un.h>
101
102 #include <semaphore.h>
103
104 #include <asterisk/module.h>
105 #include <asterisk/channel.h>
106 #include <asterisk/config.h>
107 #include <asterisk/logger.h>
108 #include <asterisk/pbx.h>
109 #include <asterisk/options.h>
110 #include <asterisk/io.h>
111 #include <asterisk/frame.h>
112 #include <asterisk/translate.h>
113 #include <asterisk/cli.h>
114 #include <asterisk/musiconhold.h>
115 #include <asterisk/dsp.h>
116 #include <asterisk/translate.h>
117 #include <asterisk/file.h>
118 #include <asterisk/callerid.h>
119 #include <asterisk/indications.h>
120 #include <asterisk/app.h>
121 #include <asterisk/features.h>
122 #include <asterisk/sched.h>
123
124 #include "extension.h"
125 #include "message.h"
126 #include "lcrsocket.h"
127 #include "cause.h"
128 #include "bchannel.h"
129 #include "chan_lcr.h"
130 #include "callerid.h"
131
132 CHAN_LCR_STATE // state description structure
133
134 int lcr_debug=1;
135 int mISDN_created=1;
136
137 char lcr_type[]="lcr";
138
139 pthread_t chan_tid;
140 ast_mutex_t chan_lock;
141 int quit;
142
143 int glob_channel = 0;
144
145 int lcr_sock = -1;
146
147 struct admin_list {
148         struct admin_list *next;
149         struct admin_msg msg;
150 } *admin_first = NULL;
151
152 static struct ast_channel_tech lcr_tech;
153
154 /*
155  * channel and call instances
156  */
157 struct chan_call *call_first;
158
159 struct chan_call *find_call_ref(unsigned long ref)
160 {
161         struct chan_call *call = call_first;
162
163         while(call)
164         {
165                 if (call->ref == ref)
166                         break;
167                 call = call->next;
168         }
169         return(call);
170 }
171
172 #if 0
173 struct chan_call *find_call_ast(struct ast_channel *ast)
174 {
175         struct chan_call *call = call_first;
176
177         while(call)
178         {
179                 if (call->ast == ast)
180                         break;
181                 call = call->next;
182         }
183         return(call);
184 }
185
186 struct chan_call *find_call_handle(unsigned long handle)
187 {
188         struct chan_call *call = call_first;
189
190         while(call)
191         {
192                 if (call->bchannel_handle == handle)
193                         break;
194                 call = call->next;
195         }
196         return(call);
197 }
198 #endif
199
200 struct chan_call *alloc_call(void)
201 {
202         struct chan_call **callp = &call_first;
203
204         while(*callp)
205                 callp = &((*callp)->next);
206
207         *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
208         if (*callp)
209                 memset(*callp, 0, sizeof(struct chan_call));
210         if (pipe((*callp)->pipe) < 0) {
211                 free_call(*callp);
212                 return;
213         }
214         return(*callp);
215 }
216
217
218 void free_call(struct chan_call *call)
219 {
220         struct chan_call **temp = &call_first;
221
222         while(*temp)
223         {
224                 if (*temp == call)
225                 {
226                         *temp = (*temp)->next;
227                         if (call->pipe[0])
228                                 close(call->pipe[0]);
229                         if (call->pipe[1])
230                                 close(call->pipe[1]);
231                         if (call->bchannel)
232                         {
233                                 if (call->bchannel->call)
234                                         call->bchannel->call = NULL;
235                                 else
236                                         warnung
237                         }
238                         if (call->bridge_call)
239                         {
240                                 if (call->bridge_call->bridge_call)
241                                         call->bridge_call->bridge_call = NULL;
242                                 else
243                                         warnung
244                         }
245                         free(call);
246                         return;
247                 }
248                 temp = &((*temp)->next);
249         }
250 }
251
252 unsigned short new_bridge_id(void)
253 {
254         struct chan_call *call;
255         unsigned short id = 1;
256
257         /* search for lowest bridge id that is not in use and not 0 */
258         while(id)
259         {
260                 call = call_first;
261                 while(call)
262                 {
263                         if (call->bridge_id == id)
264                                 break;
265                         call = call->next;
266                 }
267                 if (!call)
268                         break;
269                 id++;
270         }
271         return(id);
272 }
273
274
275 /*
276  * receive bchannel data
277  */
278 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
279 {
280 }
281
282 void rx_dtmf(struct bchannel *bchannel, char tone)
283 {
284 }
285
286 /*
287  * enque message to LCR
288  */
289 int send_message(int message_type, unsigned long ref, union parameter *param)
290 {
291         struct admin_list *admin, **adminp;
292
293         adminp = &admin_first;
294         while(*adminp)
295                 adminp = &((*adminp)->next);
296         admin = (struct admin_list *)malloc(sizeof(struct admin_list));
297         *adminp = admin;
298
299         admin->msg.type = message_type;
300         admin->msg.ref = ref;
301         memcpy(&admin->msg.param, param, sizeof(union parameter));
302
303         return(0);
304 }
305
306 /*
307  * send setup info to LCR
308  * this function is called, when asterisk call is received and ref is received
309  */
310 static void send_setup_to_lcr(struct chan_call *call)
311 {
312         union parameter newparam;
313         struct ast_channel *ast = call->ast;
314
315         if (!call->ast || !call->ref)
316                 return;
317
318         /* send setup message to LCR */
319         memset(&newparam, 0, sizeof(union parameter));
320         newparam.setup.callerinfo.itype = INFO_ITYPE_CHAN;      
321         newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;   
322         if (ast->cid.cid_num) if (ast->cid.cid_num[0])
323                 strncpy(newparam.setup.callerinfo.id, ast->cid.cid_num, sizeof(newparam.setup.callerinfo.id)-1);
324         if (ast->cid.cid_name) if (ast->cid.cid_name[0])
325                 strncpy(newparam.setup.callerinfo.name, ast->cid.cid_name, sizeof(newparam.setup.callerinfo.name)-1);
326         if (ast->cid.cid_rdnis) if (ast->cid.cid_rdnis[0])
327         {
328                 strncpy(newparam.setup.redirinfo.id, ast->cid.cid_rdnis, sizeof(newparam.setup.redirinfo.id)-1);
329                 newparam.setup.redirinfo.itype = INFO_ITYPE_CHAN;       
330                 newparam.setup.redirinfo.ntype = INFO_NTYPE_UNKNOWN;    
331         }
332         switch(ast->cid.cid_pres & AST_PRES_RESTRICTION)
333         {
334                 case AST_PRES_ALLOWED:
335                 newparam.setup.callerinfo.present = INFO_PRESENT_ALLOWED;
336                 break;
337                 case AST_PRES_RESTRICTED:
338                 newparam.setup.callerinfo.present = INFO_PRESENT_RESTRICTED;
339                 break;
340                 case AST_PRES_UNAVAILABLE:
341                 newparam.setup.callerinfo.present = INFO_PRESENT_NOTAVAIL;
342                 break;
343                 default:
344                 newparam.setup.callerinfo.present = INFO_PRESENT_NULL;
345         }
346         switch(ast->cid.cid_ton)
347         {
348                 case 4:
349                 newparam.setup.callerinfo.ntype = INFO_NTYPE_SUBSCRIBER;
350                 break;
351                 case 2:
352                 newparam.setup.callerinfo.ntype = INFO_NTYPE_NATIONAL;
353                 break;
354                 case 1:
355                 newparam.setup.callerinfo.ntype = INFO_NTYPE_INTERNATIONAL;
356                 break;
357                 default:
358                 newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
359         }
360         newparam.setup.capainfo.bearer_capa = ast->transfercapability;
361 #warning todo
362 //      newparam.setup.capainfo.bearer_user = alaw 3, ulaw 2;
363         newparam.setup.capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
364         newparam.setup.capainfo.hlc = INFO_HLC_NONE;
365         newparam.setup.capainfo.exthlc = INFO_HLC_NONE;
366         send_message(MESSAGE_SETUP, call->ref, &newparam);
367
368         /* change to outgoing setup state */
369         call->state = CHAN_LCR_STATE_OUT_SETUP;
370 }
371
372 /*
373  * send dialing info to LCR
374  * this function is called, when setup acknowledge is received and dialing
375  * info is available.
376  */
377 static void send_dialque_to_lcr(struct chan_call *call)
378 {
379         union parameter newparam;
380
381         if (!call->ast || !call->ref || !call->dialque)
382                 return;
383         
384         /* send setup message to LCR */
385         memset(&newparam, 0, sizeof(union parameter));
386         strncpy(newparam.information.id, call->dialque, sizeof(newparam.information.id)-1);
387         call->dialque[0] = '\0';
388         send_message(MESSAGE_INFORMATION, call->ref, &newparam);
389 }
390
391 /*
392  * in case of a bridge, the unsupported message can be forwarded directly
393  * to the remote call.
394  */
395 static void bridge_message_if_bridged(struct chan_call *call, int message_type, union parameter *param)
396 {
397         /* check bridge */
398         if (!call) return;
399         if (!call->bridge_call) return;
400         send_message(message_type, call->bridge_call->ref, param);
401 }
402
403 /*
404  * check if extension matches and start asterisk
405  * if it can match, proceed
406  * if not, release
407  */
408 static void lcr_setup_pbx(struct chan_call *call, struct ast_channel *ast, int complete)
409 {
410         int cause;
411
412         if (complete)
413         {
414                 /* if not match */
415                 if (!ast_canmatch_extension(ast, ast->context, call->dad, 1, call->oad))
416                 {
417                         cause = 1;
418                         goto release;
419                 if (!ast_exists_extension(ast, ast->context, call->dad, 1, call->oad))
420                 {
421                         cause = 28;
422                         goto release;
423                 }
424                 /* send setup acknowledge to lcr */
425                 memset(&newparam, 0, sizeof(union parameter));
426                 send_message(MESSAGE_PROCEEDING, call->ref, &newparam);
427
428                 /* change state */
429                 call->state = CHAN_LCR_STATE_IN_PROCEEDING;
430
431                 goto start;
432         }
433
434         if (ast_canmatch_extension(ast, ast->context, dad, 1, oad))
435         {
436                 /* send setup acknowledge to lcr */
437                 memset(&newparam, 0, sizeof(union parameter));
438                 send_message(MESSAGE_OVERLAP, call->ref, &newparam);
439
440                 /* change state */
441                 call->state = CHAN_LCR_STATE_IN_DIALING;
442
443                 /* if match, start pbx */
444                 if (ast_exists_extension(ast, ast->context, dad, 1, oad))
445                         goto start;
446
447                 /* if can match */
448                 return;
449         }
450
451         /* if not match */
452         cause = 1;
453         release:
454         /* release lcr */
455         memset(&newparam, 0, sizeof(union parameter));
456         newparam.disconnectinfo.cause = cause;
457         newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
458         send_message(MESSAGE_RELEASE, call->ref, &newparam);
459         call->ref = 0;
460         /* release asterisk */
461         ast->hangupcause = call->cause;
462         ast_queue_hangup(ast);
463         /* change to release state */
464         call->state = CHAN_LCR_STATE_RELEASE;
465         return;
466         
467         start:
468         /* send setup to asterisk */
469         ret = ast_pbx_start(ast);
470         if (ret < 0)
471         {
472                 cause = (ret==-2)?34:27;
473                 goto release;
474         }
475         call->pbx_started = 1;
476         return;
477 }
478
479 /*
480  * incoming setup from LCR
481  */
482 static void lcr_in_setup(struct chan_call *call, int message_type, union parameter *param)
483 {
484         struct ast_channel *ast;
485         union parameter newparam;
486
487         /* create asterisk channel instrance */
488         ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
489         if (!ast)
490         {
491                 /* release */
492                 memset(&newparam, 0, sizeof(union parameter));
493                 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
494                 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
495                 send_message(MESSAGE_RELEASE, call->ref, &newparam);
496                 /* remove call */
497                 free_call(call);
498                 return;
499         }
500         /* set ast pointer */
501         call->ast = ast;
502         ast->tech_pvt = call;
503         ast->tech = &lcr_tech;
504         ast->fds[0] = call->pipe[0];
505         
506         /* fill setup information */
507         if (param->setup.dialinginfo.id)
508                 strncpy(ast->exten, param->setup.dialinginfo.id, AST_MAX_EXTENSION-1);
509         if (param->setup.context[0])
510                 strncpy(ast->context, param->setup.exten, AST_MAX_CONTEXT-1);
511         if (param->setup.callerinfo.id[0])
512                 ast->cid.cid_num = strdup(param->setup.callerinfo.id);
513         if (param->setup.callerinfo.name[0])
514                 ast->cid.cid_name = strdup(param->setup.callerinfo.name);
515 #warning todo
516 #if 0
517         if (param->setup.redirinfo.id[0])
518                 ast->cid.cid_name = strdup(numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, configfile->prefix_nat, configfile->prefix_inter));
519 #endif
520         switch (param->setup.callerinfo.present)
521         {
522                 case INFO_PRESENT_ALLOWED:
523                         ast->cid.cid_pres = AST_PRES_ALLOWED;
524                 break;
525                 case INFO_PRESENT_RESTRICTED:
526                         ast->cid.cid_pres = AST_PRES_RESTRICTED;
527                 break;
528                 default:
529                         ast->cid.cid_pres = AST_PRES_UNAVAILABLE;
530         }
531         switch (param->setup.callerinfo.ntype)
532         {
533                 case INFO_NTYPE_SUBSCRIBER:
534                         ast->cid.cid_ton = 4;
535                 break;
536                 case INFO_NTYPE_NATIONAL:
537                         ast->cid.cid_ton = 2;
538                 break;
539                 case INFO_NTYPE_INTERNATIONAL:
540                         ast->cid.cid_ton = 1;
541                 break;
542                 default:
543                         ast->cid.cid_ton = 0;
544         }
545         ast->transfercapability = param->setup.capainfo.bearer_capa;
546         strcpy(call->dad, param->setup.dialinginfo.id);
547         strcpy(call->oad, numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, configfile->prefix_nat, configfile->prefix_inter));
548
549         /* configure channel */
550 #warning todo
551 #if 0
552         ast->nativeformat = configfile->lawformat;
553         ast->readformat = ast->rawreadformat = configfile->lawformat;
554         ast->writeformat = ast->rawwriteformat = configfile->lawformat;
555 #endif
556         ast->hangupcause = 0;
557
558         /* change state */
559         call->state = CHAN_LCR_STATE_IN_SETUP;
560
561         lcr_start_pbx(call, ast, param->setup.dialinginfo.complete);
562 }
563
564 /*
565  * incoming setup acknowledge from LCR
566  */
567 static void lcr_in_overlap(struct chan_call *call, int message_type, union parameter *param)
568 {
569         if (!call->ast) return;
570
571         /* send pending digits in dialque */
572         if (call->dialque)
573                 send_dialque_to_lcr(call);
574         /* change to overlap state */
575         call->state = CHAN_LCR_STATE_OUT_DIALING;
576 }
577
578 /*
579  * incoming proceeding from LCR
580  */
581 static void lcr_in_proceeding(struct chan_call *call, int message_type, union parameter *param)
582 {
583         /* change state */
584         call->state = CHAN_LCR_STATE_OUT_PROCEEDING;
585         /* send event to asterisk */
586         if (call->ast)
587                 ast_queue_control(call->ast, AST_CONTROL_PROCEEDING);
588 }
589
590 /*
591  * incoming alerting from LCR
592  */
593 static void lcr_in_alerting(struct chan_call *call, int message_type, union parameter *param)
594 {
595         /* change state */
596         call->state = CHAN_LCR_STATE_OUT_ALERTING;
597         /* send event to asterisk */
598         if (call->ast)
599                 ast_queue_control(call->ast, AST_CONTROL_RINGING);
600 }
601
602 /*
603  * incoming connect from LCR
604  */
605 static void lcr_in_connect(struct chan_call *call, int message_type, union parameter *param)
606 {
607         /* change state */
608         call->state = CHAN_LCR_STATE_CONNECT;
609         /* copy connectinfo */
610         memcpy(&call->connectinfo, &param->connectinfo, sizeof(struct connect_info));
611         /* send event to asterisk */
612         if (call->ast)
613                 ast_queue_control(call->ast, AST_CONTROL_ANSWER);
614 }
615
616 /*
617  * incoming disconnect from LCR
618  */
619 static void lcr_in_disconnect(struct chan_call *call, int message_type, union parameter *param)
620 {
621         struct ast_channel *ast = call->ast;
622         union parameter newparam;
623
624         /* change state */
625         call->state = CHAN_LCR_STATE_IN_DISCONNECT;
626         /* save cause */
627         call->cause = param->disconnectinfo.cause;
628         call->location = param->disconnectinfo.location;
629 per option
630
631 wenn setup raus geht, pointer 
632         /* if bridge, forward disconnect and return */
633         if (call->bridge_call)
634         {
635                 bridge_message_if_bridged(call, message_type, param);
636                 return;
637         }
638         /* release lcr */
639         newparam.disconnectinfo.cause = CAUSE_NORMAL;
640         newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
641         send_message(MESSAGE_RELEASE, call->ref, &newparam);
642         call->ref = 0;
643         /* release asterisk */
644         ast->hangupcause = call->cause;
645         ast_queue_hangup(ast);
646         /* change to release state */
647         call->state = CHAN_LCR_STATE_RELEASE;
648 }
649
650 /*
651  * incoming setup acknowledge from LCR
652  */
653 static void lcr_in_release(struct chan_call *call, int message_type, union parameter *param)
654 {
655         struct ast_channel *ast = call->ast;
656
657         /* release ref */
658         call->ref = 0;
659         /* change to release state */
660         call->state = CHAN_LCR_STATE_RELEASE;
661         /* copy release info */
662         if (!call->cause)
663         {
664                call->cause = param->disconnectinfo.cause;
665                call->location = param->disconnectinfo.location;
666         }
667         /* if we have an asterisk instance, send hangup, else we are done */
668         if (ast)
669         {
670                 ast->hangupcause = call->cause;
671                 ast_queue_hangup(ast);
672         } else
673         {
674                 free_call(call);
675         }
676         
677 }
678
679 /*
680  * incoming information from LCR
681  */
682 static void lcr_in_information(struct chan_call *call, int message_type, union parameter *param)
683 {
684         struct ast_frame fr;
685         char *p;
686
687         if (!call->ast) return;
688
689         /* pbx not started */
690         if (!call->pbx_started)
691         {
692                 strncat(ast->exten, param->information.id, AST_MAX_EXTENSION-1);
693                 lcr_start_pbx(call, ast, param->information.complete);
694                 return;
695         }
696         
697         /* copy digits */
698         p = param->information.id;
699         if (call->state == CHAN_LCR_STATE_IN_DIALING && *p)
700         {
701                 while (*p)
702                 {
703                         /* send digit to asterisk */
704                         memset(&fr, 0, sizeof(fr));
705                         fr.frametype = AST_FRAME_DTMF;
706                         fr.subclass = *p;
707                         fr.delivery = ast_tv(0, 0);
708                         ast_queue_frame(call->ast, &fr);
709                         p++;
710                 }
711         }
712         /* use bridge to forware message not supported by asterisk */
713         if (call->state == CHAN_LCR_STATE_CONNECT)
714                 bridge_message_if_bridged(call, message_type, param);
715 }
716
717 /*
718  * incoming information from LCR
719  */
720 static void lcr_in_notify(struct chan_call *call, int message_type, union parameter *param)
721 {
722         if (!call->ast) return;
723
724         /* use bridge to forware message not supported by asterisk */
725         bridge_message_if_bridged(call, message_type, param);
726 }
727
728 /*
729  * incoming information from LCR
730  */
731 static void lcr_in_facility(struct chan_call *call, int message_type, union parameter *param)
732 {
733         if (!call->ast) return;
734
735         /* use bridge to forware message not supported by asterisk */
736         bridge_message_if_bridged(call, message_type, param);
737 }
738
739 /*
740  * message received from LCR
741  */
742 int receive_message(int message_type, unsigned long ref, union parameter *param)
743 {
744         union parameter newparam;
745         struct bchannel *bchannel;
746         struct chan_call *call;
747
748         memset(&newparam, 0, sizeof(union parameter));
749
750         /* handle bchannel message*/
751         if (message_type == MESSAGE_BCHANNEL)
752         {
753                 switch(param->bchannel.type)
754                 {
755                         case BCHANNEL_ASSIGN:
756                         if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
757                         {
758                                 fprintf(stderr, "error: bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
759                                 return(-1);
760                         }
761                         /* create bchannel */
762                         bchannel = alloc_bchannel(param->bchannel.handle);
763                         if (!bchannel)
764                         {
765                                 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
766                                 return(-1);
767                         }
768
769                         /* configure channel */
770                         bchannel->b_tx_gain = param->bchannel.tx_gain;
771                         bchannel->b_rx_gain = param->bchannel.rx_gain;
772                         strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
773                         if (param->bchannel.crypt_len)
774                         {
775                                 bchannel->b_crypt_len = param->bchannel.crypt_len;
776                                 bchannel->b_crypt_type = param->bchannel.crypt_type;
777                                 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
778                         }
779                         bchannel->b_txdata = 0;
780                         bchannel->b_dtmf = 1;
781                         bchannel->b_tx_dejitter = 1;
782
783                         /* in case, ref is not set, this bchannel instance must
784                          * be created until it is removed again by LCR */
785                         /* link to call */
786                         if ((call = find_call_ref(ref)))
787                         {
788                                 bchannel->call = call;
789                                 call->bchannel = bchannel;
790 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
791                                 if (call->bridge_id)
792                                         bchannel_join(bchannel, call->bridge_id);
793                         }
794                         if (bchannel_create(bchannel))
795                                 bchannel_activate(bchannel, 1);
796
797                         /* acknowledge */
798                         newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
799                         newparam.bchannel.handle = param->bchannel.handle;
800                         send_message(MESSAGE_BCHANNEL, 0, &newparam);
801                         break;
802
803                         case BCHANNEL_REMOVE:
804                         if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
805                         {
806                                 #warning alle fprintf nach ast_log
807                                 fprintf(stderr, "error: bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
808                                 return(-1);
809                         }
810                         /* unklink from call and destroy bchannel */
811                         free_bchannel(bchannel);
812
813                         /* acknowledge */
814                         newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
815                         newparam.bchannel.handle = param->bchannel.handle;
816                         send_message(MESSAGE_BCHANNEL, 0, &newparam);
817                         
818                         break;
819
820                         default:
821                         fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
822                 }
823                 return(0);
824         }
825
826         /* handle new ref */
827         if (message_type == MESSAGE_NEWREF)
828         {
829                 if (param->direction)
830                 {
831                         /* new ref from lcr */
832                         if (!ref || find_call_ref(ref))
833                         {
834                                 fprintf(stderr, "illegal new ref %ld received\n", ref);
835                                 return(-1);
836                         }
837                         /* allocate new call instance */
838                         call = alloc_call();
839                         /* new state */
840                         call->state = CHAN_LCR_STATE_IN_PREPARE;
841                         /* set ref */
842                         call->ref = ref;
843                         /* wait for setup (or release from asterisk) */
844                 } else
845                 {
846                         /* new ref, as requested from this remote application */
847                         call = find_call_ref(0);
848                         if (!call)
849                         {
850                                 /* send release, if ref does not exist */
851                                 newparam.disconnectinfo.cause = CAUSE_NORMAL;
852                                 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
853                                 send_message(MESSAGE_RELEASE, ref, &newparam);
854                                 return(0);
855                         }
856                         /* store new ref */
857                         call->ref = ref;
858                         /* send pending setup info */
859                         if (call->state == CHAN_LCR_STATE_OUT_PREPARE)
860                                 send_setup_to_lcr(call);
861                         /* release if asterisk has signed off */
862                         else if (call->state == CHAN_LCR_STATE_RELEASE)
863                         {
864                                 /* send release */
865                                 if (call->cause)
866                                 {
867                                         newparam.disconnectinfo.cause = call->cause;
868                                         newparam.disconnectinfo.location = call->location;
869                                 } else
870                                 {
871                                         newparam.disconnectinfo.cause = 16;
872                                         newparam.disconnectinfo.location = 5;
873                                 }
874                                 send_message(MESSAGE_RELEASE, ref, &newparam);
875                                 /* free call */
876                                 free_call(call);
877                                 return(0);
878                         }
879                 }
880                 return(0);
881         }
882
883         /* check ref */
884         if (!ref)
885         {
886                 fprintf(stderr, "received message %d without ref\n", message_type);
887                 return(-1);
888         }
889         call = find_call_ref(ref);
890         if (!call)
891         {
892                 /* ignore ref that is not used (anymore) */
893                 return(0);
894         }
895
896         /* handle messages */
897         switch(message_type)
898         {
899                 case MESSAGE_SETUP:
900                 lcr_in_setup(call, message_type, param);
901                 break;
902
903                 case MESSAGE_OVERLAP:
904                 lcr_in_overlap(call, message_type, param);
905                 break;
906
907                 case MESSAGE_PROCEEDING:
908                 lcr_in_proceeding(call, message_type, param);
909                 break;
910
911                 case MESSAGE_ALERTING:
912                 lcr_in_alerting(call, message_type, param);
913                 break;
914
915                 case MESSAGE_CONNECT:
916                 lcr_in_connect(call, message_type, param);
917                 break;
918
919                 case MESSAGE_DISCONNECT:
920                 lcr_in_disconnect(call, message_type, param);
921                 break;
922
923                 case MESSAGE_RELEASE:
924                 lcr_in_release(call, message_type, param);
925                 break;
926
927                 case MESSAGE_INFORMATION:
928                 lcr_in_information(call, message_type, param);
929                 break;
930
931                 case MESSAGE_NOTIFY:
932                 lcr_in_notify(call, message_type, param);
933                 break;
934
935                 case MESSAGE_FACILITY:
936                 lcr_in_facility(call, message_type, param);
937                 break;
938
939                 case MESSAGE_PATTERN:
940 #warning todo
941                 break;
942
943                 case MESSAGE_NOPATTERN:
944 #warning todo
945                 break;
946
947                 case MESSAGE_AUDIOPATH:
948 #warning todo
949                 break;
950
951                 default:
952 #warning unhandled
953                 break;
954         }
955         return(0);
956 }
957
958
959 /* asterisk handler
960  * warning! not thread safe
961  * returns -1 for socket error, 0 for no work, 1 for work
962  */
963 int handle_socket(void)
964 {
965         int work = 0;
966         int len;
967         struct admin_message msg;
968         struct admin_list *admin;
969
970         int sock;
971
972         #warning SOCKET FEHLT!
973         /* read from socket */
974         len = read(sock, &msg, sizeof(msg));
975         if (len == 0)
976         {
977                 printf("Socket closed\n");
978                 return(-1); // socket closed
979         }
980         if (len > 0)
981         {
982                 if (len != sizeof(msg))
983                 {
984                         fprintf(stderr, "Socket short read (%d)\n", len);
985                         return(-1); // socket error
986                 }
987                 if (msg.message != ADMIN_MESSAGE)
988                 {
989                         fprintf(stderr, "Socket received illegal message %d\n", msg.message);
990                         return(-1); // socket error
991                 }
992                 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
993                 printf("message received %d\n", msg.u.msg.type);
994                 work = 1;
995         } else
996         {
997                 if (errno != EWOULDBLOCK)
998                 {
999                         fprintf(stderr, "Socket error %d\n", errno);
1000                         return(-1);
1001                 }
1002         }
1003
1004         /* write to socket */
1005         if (!admin_first)
1006                 return(work);
1007         admin = admin_first;
1008         len = write(sock, &admin->msg, sizeof(msg));
1009         if (len == 0)
1010         {
1011                 printf("Socket closed\n");
1012                 return(-1); // socket closed
1013         }
1014         if (len > 0)
1015         {
1016                 if (len != sizeof(msg))
1017                 {
1018                         fprintf(stderr, "Socket short write (%d)\n", len);
1019                         return(-1); // socket error
1020                 }
1021                 /* free head */
1022                 admin_first = admin->next;
1023                 free(admin);
1024
1025                 work = 1;
1026         } else
1027         {
1028                 if (errno != EWOULDBLOCK)
1029                 {
1030                         fprintf(stderr, "Socket error %d\n", errno);
1031                         return(-1);
1032                 }
1033         }
1034
1035         return(work);
1036 }
1037
1038 /*
1039  * open and close socket and thread
1040  */
1041 int open_socket(void)
1042 {
1043         int ret;
1044         int sock;
1045         char *socket_name = SOCKET_NAME;
1046         int conn;
1047         struct sockaddr_un sock_address;
1048         unsigned long on = 1;
1049         union parameter param;
1050
1051         /* open socket */
1052         if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1053         {
1054                 ast_log(LOG_ERROR, "Failed to create socket.\n");
1055                 return(sock);
1056         }
1057
1058         /* set socket address and name */
1059         memset(&sock_address, 0, sizeof(sock_address));
1060         sock_address.sun_family = PF_UNIX;
1061         strcpy(sock_address.sun_path, socket_name);
1062
1063         /* connect socket */
1064         if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
1065         {
1066                 close(sock);
1067                 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
1068                 return(conn);
1069         }
1070
1071         /* set non-blocking io */
1072         if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
1073         {
1074                 close(sock);
1075                 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
1076                 return(ret);
1077         }
1078
1079         /* enque hello message */
1080         memset(&param, 0, sizeof(param));
1081         strcpy(param.hello.application, "asterisk");
1082         send_message(MESSAGE_HELLO, 0, &param);
1083
1084         return(sock);
1085 }
1086
1087 void close_socket(int sock)
1088 {
1089         /* close socket */
1090         if (socket >= 0)        
1091                 close(sock);
1092 }
1093
1094 static void *chan_thread(void *arg)
1095 {
1096         int work;
1097         int ret;
1098
1099         ast_mutex_lock(&chan_lock);
1100
1101         while(!quit)
1102         {
1103                 work = 0;
1104
1105                 /* handle socket */
1106                 ret = handle_socket();
1107                 if (ret < 0)
1108                         break;
1109                 if (ret)
1110                         work = 1;
1111
1112                 /* handle mISDN */
1113                 ret = bchannel_handle();
1114                 if (ret)
1115                         work = 1;
1116                 
1117                 if (!work)
1118                 {
1119                         ast_mutex_unlock(&chan_lock);
1120                         usleep(30000);
1121                         ast_mutex_lock(&chan_lock);
1122                 }
1123         }
1124         
1125         ast_mutex_unlock(&chan_lock);
1126
1127         return NULL;
1128 }
1129
1130 /*
1131  * new asterisk instance
1132  */
1133 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
1134 {
1135         union parameter newparam;
1136         struct ast_channel *ast;
1137         struct chan_call *call;
1138
1139         ast_mutex_lock(&chan_lock);
1140
1141         /* create call instance */
1142         call = alloc_call();
1143         if (!call)
1144         {
1145                 /* failed to create instance */
1146                 return NULL;
1147         }
1148         /* create asterisk channel instrance */
1149         ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
1150         if (!ast)
1151         {
1152                 free_call(call);
1153                 /* failed to create instance */
1154                 return NULL;
1155         }
1156         /* link together */
1157         ast->tech_pvt = call;
1158         call->ast = ast;
1159         ast->tech = &lcr_tech;
1160         /* configure channel */
1161         snprintf(ast->name, sizeof(ast->name), "%s/%d", lcr_type, ++glob_channel);
1162         ast->name[sizeof(ast->name)-1] = '\0';
1163 #warning todo
1164 #if 0
1165         ast->nativeformat = configfile->lawformat;
1166         ast->readformat = ast->rawreadformat = configfile->lawformat;
1167         ast->writeformat = ast->rawwriteformat = configfile->lawformat;
1168 #endif
1169         ast->hangupcause = 0;
1170         /* send MESSAGE_NEWREF */
1171         memset(&newparam, 0, sizeof(union parameter));
1172         newparam.direction = 0; /* request from app */
1173         send_message(MESSAGE_NEWREF, 0, &newparam);
1174         /* set state */
1175         call->state = CHAN_LCR_STATE_OUT_PREPARE;
1176
1177         ast_mutex_unlock(&chan_lock);
1178
1179         return ast;
1180 }
1181
1182 /*
1183  * call from asterisk
1184  */
1185 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
1186 {
1187         struct chan_call *call;
1188
1189         ast_mutex_lock(&chan_lock);
1190         call = ast->tech_pvt;
1191         if (!call) {
1192                 ast_mutex_unlock(&chan_lock);
1193                 return -1;
1194         }
1195
1196
1197 #warning        hier muss noch
1198 #if 0
1199         ast_copy_string(buf, dest, sizeof(buf)-1);
1200         p=buf;
1201         port_str=strsep(&p, "/");
1202         dad=strsep(&p, "/");
1203 #endif
1204
1205         /* send setup message, if we already have a callref */
1206         if (call->ref)
1207                 send_setup_to_lcr(call);
1208
1209 //        if (lcr_debug)
1210   //              ast_verbose("Call: ext:%s dest:(%s) -> dad(%s) \n", ast->exten,dest, dad);
1211
1212         ast_mutex_unlock(&chan_lock);
1213         return 0; 
1214 }
1215
1216 static int lcr_digit(struct ast_channel *ast, char digit)
1217 {
1218         struct chan_call *call;
1219         union parameter newparam;
1220         char buf[]="x";
1221
1222         /* only pass IA5 number space */
1223         if (digit > 126 || digit < 32)
1224                 return 0;
1225
1226         ast_mutex_lock(&chan_lock);
1227         call = ast->tech_pvt;
1228         if (!call) {
1229                 ast_mutex_unlock(&chan_lock);
1230                 return -1;
1231         }
1232
1233         /* send information or queue them */
1234         if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING)
1235         {
1236                 memset(&newparam, 0, sizeof(union parameter));
1237                 newparam.information.id[0] = digit;
1238                 newparam.information.id[1] = '\0';
1239                 send_message(MESSAGE_INFORMATION, call->ref, &newparam);
1240         } else
1241         if (!call->ref
1242          && (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP));
1243         {
1244                 *buf = digit;
1245                 strncat(call->dialque, buf, strlen(call->dialque)-1);
1246         }
1247
1248         ast_mutex_unlock(&chan_lock);
1249         
1250         return(0);
1251 }
1252
1253 static int lcr_answer(struct ast_channel *ast)
1254 {
1255         union parameter newparam;
1256         struct chan_call *call;
1257
1258         ast_mutex_lock(&chan_lock);
1259         call = ast->tech_pvt;
1260         if (!call) {
1261                 ast_mutex_unlock(&chan_lock);
1262                 return -1;
1263         }
1264         
1265         /* copy connectinfo, if bridged */
1266         if (call->bridge_call)
1267                 memcpy(&call->connectinfo, &call->bridge_call->connectinfo, sizeof(struct connect_info));
1268         /* send connect message to lcr */
1269         memset(&newparam, 0, sizeof(union parameter));
1270         memcpy(&newparam.connectinfo, &call->connectinfo, sizeof(struct connect_info));
1271         send_message(MESSAGE_CONNECT, call->ref, &newparam);
1272         /* change state */
1273         call->state = CHAN_LCR_STATE_CONNECT;
1274         
1275         ast_mutex_unlock(&chan_lock);
1276         return 0;
1277 }
1278
1279 static int lcr_hangup(struct ast_channel *ast)
1280 {
1281         union parameter newparam;
1282         struct chan_call *call;
1283
1284         ast_mutex_lock(&chan_lock);
1285         call = ast->tech_pvt;
1286         if (!call) {
1287                 ast_mutex_unlock(&chan_lock);
1288                 return -1;
1289         }
1290
1291         /* disconnect asterisk, maybe not required */
1292         ast->tech_pvt = NULL;
1293         ast->fds[0] = -1;
1294         if (call->ref)
1295         {
1296                 /* release */
1297                 memset(&newparam, 0, sizeof(union parameter));
1298                 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
1299                 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1300                 send_message(MESSAGE_RELEASE, call->ref, &newparam);
1301                 /* remove call */
1302                 free_call(call);
1303                 ast_mutex_unlock(&chan_lock);
1304                 return 0;
1305         } else
1306         {
1307                 /* ref is not set, due to prepare setup or release */
1308                 if (call->state == CHAN_LCR_STATE_RELEASE)
1309                 {
1310                         /* we get the response to our release */
1311                         free_call(call);
1312                 } else
1313                 {
1314                         /* during prepare, we change to release state */
1315                         call->state = CHAN_LCR_STATE_RELEASE;
1316                 }
1317         } 
1318         ast_mutex_unlock(&chan_lock);
1319         return 0;
1320 }
1321
1322 static int lcr_write(struct ast_channel *ast, struct ast_frame *f)
1323 {
1324         struct chan_call *call;
1325         unsigned char *buffer[1024], *s, *d = buffer;
1326
1327         ast_mutex_lock(&chan_lock);
1328         call = ast->tech_pvt;
1329         if (!call) {
1330                 ast_mutex_unlock(&chan_lock);
1331                 return -1;
1332         }
1333         if (call->bchannel && ((ii = f->samples)))
1334         {
1335                 if (ii > sizeof(buffer))
1336                         ii = buffer;
1337                 s = f->data;
1338                 for (i = 0, i < ii, i++)
1339                         *d++ = flip_bits[*s++];
1340                 bchannel_transmit(call->bchannel, buffer, ii);
1341         }
1342         ast_mutex_unlock(&chan_lock);
1343         return 0;
1344 }
1345
1346
1347 static struct ast_frame *lcr_read(struct ast_channel *ast)
1348 {
1349         struct chan_call *call;
1350         int i, len;
1351         unsigned char *p;
1352
1353         ast_mutex_lock(&chan_lock);
1354         call = ast->tech_pvt;
1355         if (!call) {
1356                 ast_mutex_unlock(&chan_lock);
1357                 return -1;
1358         }
1359         len = read(call->pipe[0], call->read_buf, sizeof(call->read_buf));
1360         if (len <= 0)
1361                 return NULL;
1362
1363         p = call->read_buf;
1364         for (i = 0, i < len, i++) {
1365                 *d = flip_bits[*d];
1366                 d++;
1367         }
1368
1369         call->read_fr.frametype = AST_FRAME_SPEECH;
1370 #warning todo
1371         call->read_fr.subtype = AST_FORMAT_ALAW;
1372         call->read_fr.datalen = len;
1373         call->read_fr.samples = len;
1374         call->read_fr.delivery = ast_tv(0,0);
1375         call->read_fr.data = call->read_buf;
1376         ast_mutex_unlock(&chan_lock);
1377
1378         return &call->read_fr;
1379 }
1380
1381 static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, size_t datalen)
1382 {
1383         union parameter newparam;
1384         int res = -1;
1385         struct chan_call *call;
1386
1387         ast_mutex_lock(&chan_lock);
1388         call = ast->tech_pvt;
1389         if (!call) {
1390                 ast_mutex_unlock(&chan_lock);
1391                 return -1;
1392         }
1393
1394         switch (cond) {
1395                 case AST_CONTROL_BUSY:
1396                         /* send message to lcr */
1397                         memset(&newparam, 0, sizeof(union parameter));
1398                         newparam.disconnectinfo.cause = 17;
1399                         newparam.disconnectinfo.location = 5;
1400                         send_message(MESSAGE_DISCONNECT, call->ref, &newparam);
1401                         /* change state */
1402                         call->state = CHAN_LCR_STATE_OUT_DISCONNECT;
1403                         /* return */
1404                         ast_mutex_unlock(&chan_lock);
1405                         return 0;
1406                 case AST_CONTROL_CONGESTION:
1407                         /* return */
1408                         ast_mutex_unlock(&chan_lock);
1409                         return -1;
1410                 case AST_CONTROL_RINGING:
1411                         /* send message to lcr */
1412                         memset(&newparam, 0, sizeof(union parameter));
1413                         send_message(MESSAGE_ALERTING, call->ref, &newparam);
1414                         /* change state */
1415                         call->state = CHAN_LCR_STATE_OUT_ALERTING;
1416                         /* return */
1417                         ast_mutex_unlock(&chan_lock);
1418                         return 0;
1419                 case -1:
1420                         /* return */
1421                         ast_mutex_unlock(&chan_lock);
1422                         return 0;
1423
1424                 case AST_CONTROL_VIDUPDATE:
1425                         res = -1;
1426                         break;
1427                 case AST_CONTROL_HOLD:
1428                         /* send message to lcr */
1429                         memset(&newparam, 0, sizeof(union parameter));
1430                         newparam.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
1431                         send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1432                         break;
1433                 case AST_CONTROL_UNHOLD:
1434                         /* send message to lcr */
1435                         memset(&newparam, 0, sizeof(union parameter));
1436                         newparam.notifyinfo.notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
1437                         send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1438                         break;
1439
1440                 default:
1441                         ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, ast->name);
1442                         /* return */
1443                         ast_mutex_unlock(&chan_lock);
1444                         return -1;
1445         }
1446
1447         /* return */
1448         ast_mutex_unlock(&chan_lock);
1449         return 0;
1450 }
1451
1452 /*
1453  * bridge process
1454  */
1455 enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
1456                                   struct ast_channel *ast2, int flags,
1457                                   struct ast_frame **fo,
1458                                   struct ast_channel **rc, int timeoutms)
1459
1460 {
1461         struct chan_call        *call1, *call2;
1462         struct ast_channel      *carr[2], *who;
1463         int                     to = -1;
1464         struct ast_frame        *f;
1465         int                     bridge_id;
1466  
1467         /* join via dsp (if the channels are currently open) */
1468         ast_mutex_lock(&chan_lock);
1469         bridge_id = new_bridge_id();
1470         call1 = ast1->tech_pvt;
1471         call2 = ast2->tech_pvt;
1472         if (call1 && call2)
1473         {
1474                 call1->bridge_id = bridge_id;
1475                 if (call1->bchannel)
1476                         bchannel_join(call1->bchannel, bridge_id);
1477                 call1->bridge_call = call2;
1478         }
1479         if (call2)
1480         {
1481                 call2->bridge_id = bridge_id;
1482                 if (call2->bchannel)
1483                         bchannel_join(call2->bchannel, bridge_id);
1484                 call2->bridge_call = call1;
1485         }
1486         ast_mutex_unlock(&chan_lock);
1487         
1488         while(1) {
1489                 who = ast_waitfor_n(carr, 2, &to);
1490
1491                 if (!who) {
1492                         ast_log(LOG_NOTICE,"misdn_bridge: empty read, breaking out\n");
1493                         break;
1494                 }
1495                 f = ast_read(who);
1496     
1497                 if (!f || f->frametype == AST_FRAME_CONTROL) {
1498                         /* got hangup .. */
1499                         *fo=f;
1500                         *rc=who;
1501                         break;
1502                 }
1503                 
1504                 if ( f->frametype == AST_FRAME_DTMF ) {
1505                         *fo=f;
1506                         *rc=who;
1507                         break;
1508                 }
1509         
1510 #warning kann einfach gesendet werden. dsp slittet automatisch, wenn frames kommen, bis der fifo leer ist.
1511 #if 0
1512                 if (f->frametype == AST_FRAME_VOICE) {
1513         
1514                         continue;
1515                 }
1516 #endif
1517
1518                 if (who == ast1) {
1519                         ast_write(ast2,f);
1520                 }
1521                 else {
1522                         ast_write(ast1,f);
1523                 }
1524     
1525         }
1526         
1527         /* split channels */
1528         ast_mutex_lock(&chan_lock);
1529         call1 = ast1->tech_pvt;
1530         call2 = ast2->tech_pvt;
1531         if (call1)
1532         {
1533                 call1->bridge_id = 0;
1534                 if (call1->bchannel)
1535                         bchannel_join(call1->bchannel, 0);
1536                 if (call1->bridge_call)
1537                         call1->bridge_call->bridge_call = NULL;
1538                 call1->bridge_call = NULL;
1539         }
1540         if (call2)
1541         {
1542                 call2->bridge_id = 0;
1543                 if (call2->bchannel)
1544                         bchannel_join(call2->bchannel, 0);
1545                 if (call2->bridge_call)
1546                         call2->bridge_call->bridge_call = NULL;
1547                 call2->bridge_call = NULL;
1548         }
1549         ast_mutex_unlock(&chan_lock);
1550         
1551         
1552         return AST_BRIDGE_COMPLETE;
1553 }
1554 static struct ast_channel_tech lcr_tech = {
1555         .type=lcr_type,
1556         .description="Channel driver for connecting to Linux-Call-Router",
1557 #warning todo
1558         .capabilities=AST_FORMAT_ALAW,
1559         .requester=lcr_request,
1560         .send_digit_begin=lcr_digit,
1561         .call=lcr_call,
1562         .bridge=lcr_bridge, 
1563         .hangup=lcr_hangup,
1564         .answer=lcr_answer,
1565         .read=lcr_read,
1566         .write=lcr_write,
1567         .indicate=lcr_indicate,
1568 //      .fixup=lcr_fixup,
1569 //      .send_text=lcr_send_text,
1570         .properties=0
1571 };
1572
1573
1574 /*
1575  * cli
1576  */
1577 static int lcr_show_lcr (int fd, int argc, char *argv[])
1578 {
1579         return 0;
1580 }
1581
1582 static int lcr_show_calls (int fd, int argc, char *argv[])
1583 {
1584         return 0;
1585 }
1586
1587 static int lcr_reload_routing (int fd, int argc, char *argv[])
1588 {
1589         return 0;
1590 }
1591
1592 static int lcr_reload_interfaces (int fd, int argc, char *argv[])
1593 {
1594         return 0;
1595 }
1596
1597 static int lcr_port_block (int fd, int argc, char *argv[])
1598 {
1599         return 0;
1600 }
1601
1602 static int lcr_port_unblock (int fd, int argc, char *argv[])
1603 {
1604         return 0;
1605 }
1606
1607 static int lcr_port_unload (int fd, int argc, char *argv[])
1608 {
1609         return 0;
1610 }
1611
1612 static struct ast_cli_entry cli_show_lcr =
1613 { {"lcr", "show", "lcr", NULL},
1614  lcr_show_lcr,
1615  "Shows current states of LCR core",
1616  "Usage: lcr show lcr\n",
1617 };
1618
1619 static struct ast_cli_entry cli_show_calls =
1620 { {"lcr", "show", "calls", NULL},
1621  lcr_show_calls,
1622  "Shows current calls made by LCR and Asterisk",
1623  "Usage: lcr show calls\n",
1624 };
1625
1626 static struct ast_cli_entry cli_reload_routing =
1627 { {"lcr", "reload", "routing", NULL},
1628  lcr_reload_routing,
1629  "Reloads routing conf of LCR, current uncomplete calls will be disconnected",
1630  "Usage: lcr reload routing\n",
1631 };
1632
1633 static struct ast_cli_entry cli_reload_interfaces =
1634 { {"lcr", "reload", "interfaces", NULL},
1635  lcr_reload_interfaces,
1636  "Reloads interfaces conf of LCR",
1637  "Usage: lcr reload interfaces\n",
1638 };
1639
1640 static struct ast_cli_entry cli_port_block =
1641 { {"lcr", "port", "block", NULL},
1642  lcr_port_block,
1643  "Blocks LCR port for further calls",
1644  "Usage: lcr port block \"<port>\"\n",
1645 };
1646
1647 static struct ast_cli_entry cli_port_unblock =
1648 { {"lcr", "port", "unblock", NULL},
1649  lcr_port_unblock,
1650  "Unblocks or loads LCR port, port is opened my mISDN",
1651  "Usage: lcr port unblock \"<port>\"\n",
1652 };
1653
1654 static struct ast_cli_entry cli_port_unload =
1655 { {"lcr", "port", "unload", NULL},
1656  lcr_port_unload,
1657  "Unloads LCR port, port is closes by mISDN",
1658  "Usage: lcr port unload \"<port>\"\n",
1659 };
1660
1661
1662 /*
1663  * module loading and destruction
1664  */
1665 int load_module(void)
1666 {
1667         int i;
1668
1669         for (i = 0, i < 256, i++)
1670                 flip_bits[i] = (i>>7) | ((i>>5)&2) | ((i>>3)&4) | ((i>>1)&8)
1671                           || = (i<<7) | ((i&2)<<5) | ((i&4)<<3) | ((i&8)<<1);
1672
1673         ast_mutex_init(&chan_lock);
1674         
1675         if (!(lcr_sock = open_socket())) {
1676                 ast_log(LOG_ERROR, "Unable to connect\n");
1677                 lcr_sock = -1;
1678                 /* continue with closed socket */
1679         }
1680
1681         if (!bchannel_initialize()) {
1682                 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
1683                 close_socket(lcr_sock);
1684                 return -1;
1685         }
1686         mISDN_created = 1;
1687
1688         if (ast_channel_register(&lcr_tech)) {
1689                 ast_log(LOG_ERROR, "Unable to register channel class\n");
1690                 bchannel_deinitialize();
1691                 close_socket(lcr_sock);
1692                 return -1;
1693         }
1694  
1695 #if 0   
1696         ast_cli_register(&cli_show_lcr);
1697         ast_cli_register(&cli_show_calls);
1698
1699         ast_cli_register(&cli_reload_routing);
1700         ast_cli_register(&cli_reload_interfaces);
1701         ast_cli_register(&cli_port_block);
1702         ast_cli_register(&cli_port_unblock);
1703         ast_cli_register(&cli_port_unload);
1704   
1705         ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
1706                                  "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
1707                                  "Sets mISDN opts. and optargs\n"
1708                                  "\n"
1709                                  "The available options are:\n"
1710                                  "    d - Send display text on called phone, text is the optparam\n"
1711                                  "    n - don't detect dtmf tones on called channel\n"
1712                                  "    h - make digital outgoing call\n" 
1713                                  "    c - make crypted outgoing call, param is keyindex\n"
1714                                  "    e - perform echo cancelation on this channel,\n"
1715                                  "        takes taps as arguments (32,64,128,256)\n"
1716                                  "    s - send Non Inband DTMF as inband\n"
1717                                  "   vr - rxgain control\n"
1718                                  "   vt - txgain control\n"
1719                 );
1720
1721         
1722         lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1723
1724         chan_lcr_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
1725 =======
1726         //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1727 #endif
1728
1729         quit = 1;       
1730         if ((pthread_create(&chan_tid, NULL, chan_thread, NULL)<0))
1731         {
1732                 /* failed to create thread */
1733                 bchannel_deinitialize();
1734                 close_socket(lcr_sock);
1735                 ast_channel_unregister(&lcr_tech);
1736                 return -1;
1737         }
1738         return 0;
1739 }
1740
1741 int unload_module(void)
1742 {
1743         /* First, take us out of the channel loop */
1744         ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
1745
1746         quit = 1;
1747         pthread_join(chan_tid, NULL);   
1748         
1749         ast_channel_unregister(&lcr_tech);
1750
1751         if (mISDN_created) {
1752                 bchannel_deinitialize();
1753                 mISDN_created = 0;
1754         }
1755
1756         if (lcr_sock >= 0) {
1757                 close(lcr_sock);
1758                 lcr_sock = -1;
1759         }
1760
1761         return 0;
1762 }
1763
1764 static int reload_module(void)
1765 {
1766 //      reload_config();
1767         return 0;
1768 }
1769
1770
1771 ast_mutex_t usecnt_lock;
1772 int usecnt;
1773
1774 int usecount(void)
1775 {
1776         int res;
1777         ast_mutex_lock(&usecnt_lock);
1778         res = usecnt;
1779         ast_mutex_unlock(&usecnt_lock);
1780         return res;
1781 }
1782
1783
1784 char *desc="Channel driver for lcr";
1785
1786 char *description(void)
1787 {
1788         return desc;
1789 }
1790
1791 char *key(void)
1792 {
1793         return ASTERISK_GPL_KEY;
1794 }
1795
1796 #define AST_MODULE "chan_lcr"
1797 AST_MODULE_INFO(ASTERISK_GPL_KEY,
1798                                 AST_MODFLAG_DEFAULT,
1799                                 "Channel driver for LCR",
1800                                 .load = load_module,
1801                                 .unload = unload_module,
1802                                 .reload = reload_module,
1803                            );
1804