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