work on chan_lcr:
[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 locking asterisk process and handler
83 reconnect after socket closed, release all calls.
84 debug of call handling
85 denke an alle info-elements in jeder message (from asterisk & from lcr)
86
87
88 #include <stdio.h>
89 #include <stdlib.h>
90 #include <string.h>
91 #include <stdarg.h>
92 #include <errno.h>
93 #include <sys/types.h>
94 #include <time.h>
95 #include <unistd.h>
96 #include <fcntl.h>
97 #include <sys/ioctl.h>
98 #include <sys/socket.h>
99 #include <sys/un.h>
100
101 #include <pthread.h>
102 #include <semaphore.h>
103
104 #include "extension.h"
105 #include "message.h"
106 #include "lcrsocket.h"
107 #include "cause.h"
108 #include "bchannel.h"
109 #include "chan_lcr.h"
110
111
112
113 #include <asterisk/module.h>
114 #include <asterisk/channel.h>
115 #include <asterisk/config.h>
116 #include <asterisk/logger.h>
117 #include <asterisk/pbx.h>
118 #include <asterisk/options.h>
119 #include <asterisk/io.h>
120 #include <asterisk/frame.h>
121 #include <asterisk/translate.h>
122 #include <asterisk/cli.h>
123 #include <asterisk/musiconhold.h>
124 #include <asterisk/dsp.h>
125 #include <asterisk/translate.h>
126 #include <asterisk/file.h>
127 #include <asterisk/callerid.h>
128 #include <asterisk/indications.h>
129 #include <asterisk/app.h>
130 #include <asterisk/features.h>
131 #include <asterisk/sched.h>
132
133 CHAN_LCR_STATE // state description structure
134
135 int lcr_debug=1;
136 int mISDN_created=1;
137
138
139 int lcr_sock = -1;
140
141 struct admin_list {
142         struct admin_list *next;
143         struct admin_msg msg;
144 } *admin_first = NULL;
145
146 /*
147  * channel and call instances
148  */
149 struct chan_call *call_first;
150
151 struct chan_call *find_call_ref(unsigned long ref)
152 {
153         struct chan_call *call = call_first;
154
155         while(call)
156         {
157                 if (call->ref == ref)
158                         break;
159                 call = call->next;
160         }
161         return(call);
162 }
163
164 struct chan_call *find_call_handle(unsigned long handle)
165 {
166         struct chan_call *call = call_first;
167
168         while(call)
169         {
170                 if (call->bchannel_handle == handle)
171                         break;
172                 call = call->next;
173         }
174         return(call);
175 }
176
177 struct chan_call *alloc_call(void)
178 {
179         struct chan_call **callp = &call_first;
180
181         while(*callp)
182                 callp = &((*callp)->next);
183
184         *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
185         if (*callp)
186                 memset(*callp, 0, sizeof(struct chan_call));
187         return(*callp);
188 }
189
190 void free_call(struct chan_call *call)
191 {
192         struct chan_call **temp = &call_first;
193
194         while(*temp)
195         {
196                 if (*temp == call)
197                 {
198                         *temp = (*temp)->next;
199                         free(call);
200                         return;
201                 }
202                 temp = &((*temp)->next);
203         }
204 }
205
206 unsigned short new_brige_id(void)
207 {
208         struct chan_call *call;
209         unsigned short id = 1;
210
211         /* search for lowest bridge id that is not in use and not 0 */
212         while(id)
213         {
214                 call = call_first;
215                 while(call)
216                 {
217                         if (call->bridge_id == id)
218                                 break;
219                         call = call->next;
220                 }
221                 if (!call)
222                         break;
223                 id++;
224         }
225         return(id);
226 }
227
228
229 /*
230  * receive bchannel data
231  */
232 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
233 {
234 }
235
236 void rx_dtmf(struct bchannel *bchannel, char tone)
237 {
238 }
239
240 /*
241  * enque message to LCR
242  */
243 int send_message(int message_type, unsigned long ref, union parameter *param)
244 {
245         struct admin_list *admin, **adminp;
246
247         adminp = &admin_first;
248         while(*adminp)
249                 adminp = &((*adminp)->next);
250         admin = (struct admin_list *)malloc(sizeof(struct admin_list));
251         *adminp = admin;
252
253         admin->msg.type = message_type;
254         admin->msg.ref = ref;
255         memcpy(&admin->msg.param, param, sizeof(union parameter));
256
257         return(0);
258 }
259
260 /*
261  * incoming setup from LCR
262  */
263 static void lcr_in_setup(struct chan_call *call, int message_type, union parameter *param)
264 {
265         struct ast_channel *ast;
266         union parameter newparam;
267
268         /* create asterisk channel instrance */
269         ast = ast_channel_alloc(1);
270         if (!ast)
271         {
272                 /* release */
273                 memset(&newparam, 0, sizeof(union parameter));
274                 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
275                 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
276                 send_message(MESSAGE_RELEASE, call->ref, &newparam);
277                 /* remove call */
278                 free_call(call);
279                 return;
280         }
281         /* set ast pointer */
282         call->ast = ast;
283         
284         /* fill setup information */
285 #warning todo: setup-info reinschreiben
286
287         /* send setup to asterisk */
288 #warning todo: setup bei der asterisk triggern
289
290         /* change state */
291         call->state = CHAN_LCR_STATE_IN_SETUP;
292 }
293
294 /*
295  * incoming setup acknowledge from LCR
296  */
297 static void lcr_in_overlap(struct chan_call *call, int message_type, union parameter *param)
298 {
299         /* send pending digits in dialque */
300         if (call->dialque)
301                 send_dialing_to_lcr(call);
302         /* change to overlap state */
303         call->state = CHAN_LCR_STATE_OUT_DIALING;
304 }
305
306 /*
307  * incoming proceeding from LCR
308  */
309 static void lcr_in_proceeding(struct chan_call *call, int message_type, union parameter *param)
310 {
311         /* change state */
312         call->state = CHAN_LCR_STATE_OUT_PROCEEDING;
313         /* send event to asterisk */
314         ast_queue_... todo
315 }
316
317 /*
318  * incoming alerting from LCR
319  */
320 static void lcr_in_alerting(struct chan_call *call, int message_type, union parameter *param)
321 {
322         /* change state */
323         call->state = CHAN_LCR_STATE_OUT_ALERTING;
324         /* send event to asterisk */
325         ast_queue_... todo
326 }
327
328 /*
329  * incoming connect from LCR
330  */
331 static void lcr_in_connect(struct chan_call *call, int message_type, union parameter *param)
332 {
333         /* change state */
334         call->state = CHAN_LCR_STATE_CONNECT;
335         /* copy connectinfo */
336         todo
337         /* send event to asterisk */
338         ast_queue_... todo
339 }
340
341 /*
342  * incoming disconnect from LCR
343  */
344 static void lcr_in_disconnect(struct chan_call *call, int message_type, union parameter *param)
345 {
346         /* change state */
347         call->state = CHAN_LCR_STATE_IN_DISCONNECT;
348         /* copy disconnect info */
349         todo
350         /* send event to asterisk */
351         ast_queue_... todo
352 }
353
354 /*
355  * incoming setup acknowledge from LCR
356  */
357 static void lcr_in_release(struct chan_call *call, int message_type, union parameter *param)
358 {
359         /* release ref */
360         call->ref = NULL;
361         /* change to release state */
362         call->state = CHAN_LCR_STATE_RELEASE;
363         /* copy release info */
364         todo
365         /* if we have an asterisk instance, send hangup, else we are done */
366         if (call->ast)
367         {
368                 ast_queue_hangup(call->ast);
369         } else
370         {
371                 free_call(call);
372         }
373         
374 }
375
376 /*
377  * incoming information from LCR
378  */
379 static void lcr_in_information(struct chan_call *call, int message_type, union parameter *param)
380 {
381         /* copy digits */
382         todo and write them, maybe queue them for asterisk
383         /* send event to asterisk */
384         ast_queue_... todo
385 }
386
387 /*
388  * incoming information from LCR
389  */
390 static void lcr_in_facility(struct chan_call *call, int message_type, union parameter *param)
391 {
392         /* copy progress info */
393         todo and write them, maybe queue them for asterisk
394         /* send event to asterisk */
395         ast_queue_... todo
396         or maybe use bride info to forward facility.
397 }
398
399 /*
400  * message received from LCR
401  */
402 int receive_message(int message_type, unsigned long ref, union parameter *param)
403 {
404         union parameter newparam;
405         struct bchannel *bchannel;
406         struct chan_call *call;
407
408         memset(&newparam, 0, sizeof(union parameter));
409
410         /* handle bchannel message*/
411         if (message_type == MESSAGE_BCHANNEL)
412         {
413                 switch(param->bchannel.type)
414                 {
415                         case BCHANNEL_ASSIGN:
416                         if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
417                         {
418                                 fprintf(stderr, "error: bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
419                                 return(-1);
420                         }
421                         /* create bchannel */
422                         bchannel = alloc_bchannel(param->bchannel.handle);
423                         if (!bchannel)
424                         {
425                                 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
426                                 return(-1);
427                         }
428
429                         /* configure channel */
430                         bchannel->b_tx_gain = param->bchannel.tx_gain;
431                         bchannel->b_rx_gain = param->bchannel.rx_gain;
432                         strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
433                         if (param->bchannel.crypt_len)
434                         {
435                                 bchannel->b_crypt_len = param->bchannel.crypt_len;
436                                 bchannel->b_crypt_type = param->bchannel.crypt_type;
437                                 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
438                         }
439                         bchannel->b_txdata = 0;
440                         bchannel->b_dtmf = 1;
441                         bchannel->b_tx_dejitter = 1;
442
443                         /* in case, ref is not set, this bchannel instance must
444                          * be created until it is removed again by LCR */
445                         /* link to call */
446                         if ((call = find_call_ref(ref)))
447                         {
448                                 bchannel->ref = ref;
449                                 call->bchannel_handle = param->bchannel.handle;
450 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
451                                 bchannel_join(bchannel, call->bridge_id);
452                         }
453                         if (bchannel_create(bchannel))
454                                 bchannel_activate(bchannel, 1);
455
456                         /* acknowledge */
457                         newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
458                         newparam.bchannel.handle = param->bchannel.handle;
459                         send_message(MESSAGE_BCHANNEL, 0, &newparam);
460                         break;
461
462                         case BCHANNEL_REMOVE:
463                         if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
464                         {
465                                 #warning alle fprintf nach ast_log
466                                 fprintf(stderr, "error: bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
467                                 return(-1);
468                         }
469                         /* unlink from call */
470                         if ((call = find_call_ref(bchannel->ref)))
471                         {
472                                 call->bchannel_handle = 0;
473                         }
474                         /* destroy and remove bchannel */
475                         free_bchannel(bchannel);
476
477                         /* acknowledge */
478                         newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
479                         newparam.bchannel.handle = param->bchannel.handle;
480                         send_message(MESSAGE_BCHANNEL, 0, &newparam);
481                         
482                         break;
483
484                         default:
485                         fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
486                 }
487                 return(0);
488         }
489
490         /* handle new ref */
491         if (message_type == MESSAGE_NEWREF)
492         {
493                 if (param->direction)
494                 {
495                         /* new ref from lcr */
496                         if (!ref || find_call_ref(ref))
497                         {
498                                 fprintf(stderr, "illegal new ref %d received\n", ref);
499                                 return(-1);
500                         }
501                         /* allocate new call instance */
502                         call = alloc_call();
503                         /* new state */
504                         call->state = CHAN_LCR_STATE_IN_PREPARE;
505                         /* set ref */
506                         call->ref = ref;
507                         /* wait for setup (or release from asterisk) */
508                 } else
509                 {
510                         /* new ref, as requested from this remote application */
511                         call = find_call_ref(0);
512                         if (!call)
513                         {
514                                 /* send release, if ref does not exist */
515                                 newparam.disconnectinfo.cause = CAUSE_NORMAL;
516                                 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
517                                 send_message(MESSAGE_RELEASE, ref, &newparam);
518                                 return(0);
519                         }
520                         /* store new ref */
521                         call->ref = ref;
522                         /* send pending setup info */
523                         if (call->state == CHAN_LCR_STATE_OUT_PREPARE)
524                                 send_setup_to_lcr(call);
525                         /* release if asterisk has signed off */
526                         else if (call->state == CHAN_LCR_STATE_RELEASE)
527                         {
528                                 /* send release */
529                                 newparam.disconnectinfo.cause = todo
530                                 newparam.disconnectinfo.location = todo
531                                 send_message(MESSAGE_RELEASE, ref, &newparam);
532                                 /* free call */
533                                 free_call(call);
534                                 return(0);
535                         }
536                 }
537                 return(0);
538         }
539
540         /* check ref */
541         if (!ref)
542         {
543                 fprintf(stderr, "received message %d without ref\n", message_type);
544                 return(-1);
545         }
546         call = find_call_ref(ref);
547         if (!call)
548         {
549                 /* ignore ref that is not used (anymore) */
550                 return(0);
551         }
552
553         /* handle messages */
554         switch(message_type)
555         {
556                 case MESSAGE_SETUP:
557                 lcr_in_setup(call, message_type, param);
558                 break;
559
560                 case MESSAGE_OVERLAP:
561                 lcr_in_overlap(call, message_type, param);
562                 break;
563
564                 case MESSAGE_PROCEEDING:
565                 lcr_in_proceeding(call, message_type, param);
566                 break;
567
568                 case MESSAGE_ALERTING:
569                 lcr_in_alerting(call, message_type, param);
570                 break;
571
572                 case MESSAGE_CONNECT:
573                 lcr_in_connect(call, message_type, param);
574                 break;
575
576                 case MESSAGE_DISCONNECT:
577                 lcr_in_disconnect(call, message_type, param);
578                 break;
579
580                 case MESSAGE_RELEASE:
581                 lcr_in_release(call, message_type, param);
582                 break;
583
584                 case MESSAGE_INFORMATION:
585                 lcr_in_disconnect(call, message_type, param);
586                 break;
587
588                 case MESSAGE_FACILITY:
589                 lcr_in_disconnect(call, message_type, param);
590                 break;
591
592                 case MESSAGE_PATTERN:
593 #warning todo
594                 break;
595
596                 case MESSAGE_NOPATTERN:
597 #warning todo
598                 break;
599
600                 case MESSAGE_AUDIOPATH:
601 #warning todo
602                 break;
603
604                 default:
605 #warning unhandled
606         }
607         return(0);
608 }
609
610
611 /* asterisk handler
612  * warning! not thread safe
613  * returns -1 for socket error, 0 for no work, 1 for work
614  */
615 int handle_socket(void)
616 {
617         int work = 0;
618         int len;
619         struct admin_message msg;
620         struct admin_list *admin;
621
622         int sock;
623
624         #warning SOCKET FEHLT!
625         /* read from socket */
626         len = read(sock, &msg, sizeof(msg));
627         if (len == 0)
628         {
629                 printf("Socket closed\n");
630                 return(-1); // socket closed
631         }
632         if (len > 0)
633         {
634                 if (len != sizeof(msg))
635                 {
636                         fprintf(stderr, "Socket short read (%d)\n", len);
637                         return(-1); // socket error
638                 }
639                 if (msg.message != ADMIN_MESSAGE)
640                 {
641                         fprintf(stderr, "Socket received illegal message %d\n", msg.message);
642                         return(-1); // socket error
643                 }
644                 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
645                 printf("message received %d\n", msg.u.msg.type);
646                 work = 1;
647         } else
648         {
649                 if (errno != EWOULDBLOCK)
650                 {
651                         fprintf(stderr, "Socket error %d\n", errno);
652                         return(-1);
653                 }
654         }
655
656         /* write to socket */
657         if (!admin_first)
658                 return(work);
659         admin = admin_first;
660         len = write(sock, &admin->msg, sizeof(msg));
661         if (len == 0)
662         {
663                 printf("Socket closed\n");
664                 return(-1); // socket closed
665         }
666         if (len > 0)
667         {
668                 if (len != sizeof(msg))
669                 {
670                         fprintf(stderr, "Socket short write (%d)\n", len);
671                         return(-1); // socket error
672                 }
673                 /* free head */
674                 admin_first = admin->next;
675                 free(admin);
676
677                 work = 1;
678         } else
679         {
680                 if (errno != EWOULDBLOCK)
681                 {
682                         fprintf(stderr, "Socket error %d\n", errno);
683                         return(-1);
684                 }
685         }
686
687         return(work);
688 }
689
690 /*
691  * open and close socket
692  */
693 int open_socket(void)
694 {
695         int ret;
696         int sock;
697         char *socket_name = SOCKET_NAME;
698         int conn;
699         struct sockaddr_un sock_address;
700         unsigned long on = 1;
701         union parameter param;
702
703         /* open socket */
704         if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
705         {
706                 ast_log(LOG_ERROR, "Failed to create socket.\n");
707                 return(sock);
708         }
709
710         /* set socket address and name */
711         memset(&sock_address, 0, sizeof(sock_address));
712         sock_address.sun_family = PF_UNIX;
713         strcpy(sock_address.sun_path, socket_name);
714
715         /* connect socket */
716         if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
717         {
718                 close(sock);
719                 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
720                 return(conn);
721         }
722
723         /* set non-blocking io */
724         if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
725         {
726                 close(sock);
727                 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
728                 return(ret);
729         }
730
731         /* enque hello message */
732         memset(&param, 0, sizeof(param));
733         strcpy(param.hello.application, "asterisk");
734         send_message(MESSAGE_HELLO, 0, &param);
735
736         return(sock);
737 }
738
739 void close_socket(int sock)
740 {
741         /* close socket */
742         if (socket >= 0)        
743                 close(sock);
744 }
745
746
747 hander thread muss noch
748 socket muss per timer fuer das Ã¶ffnen checken
749 void lcr_thread(void)
750 {
751         int work;
752
753         while(42)
754         {
755                 work = 0;
756
757                 /* handle socket */
758                 int ret = handle_socket();
759                 if (ret < 0)
760                         break;
761                 if (ret)
762                         work = 1;
763
764                 /* handle mISDN */
765                 ret = bchannel_handle();
766                 if (ret)
767                         work = 1;
768                 
769                 if (!work)
770                         usleep(30000);
771         }
772 }
773
774 /*
775  * send setup info to LCR
776  * this function is called, when asterisk call is received and ref is received
777  */
778 static void send_setup_to_lcr(struct chan_call *call)
779 {
780         if (!ast || !call->ref)
781                 return;
782
783         /* send setup message to LCR */
784         memset(&newparam, 0, sizeof(union parameter));
785         newparam.setup.xxxxxx = 
786         send_message(MESSAGE_SETUP, call->ref, &newparam);
787         /* change to outgoing setup state */
788         call->state = CHAN_LCR_STATE_OUT_SETUP;
789 }
790
791 /*
792  * send dialing info to LCR
793  * this function is called, when setup acknowledge is received and dialing
794  * info is available.
795  */
796 static void send_dialing_to_lcr(struct chan_call *call)
797 {
798         if (!ast || !call->ref || !call->dialque)
799                 return;
800         
801         /* send setup message to LCR */
802         memset(&newparam, 0, sizeof(union parameter));
803         strncpy(newparam.dialinginfo.id, call->dialque, sizeof(newparam.dialinginfo.id)-1);
804         call->dialque[0] = '\0';
805         send_message(MESSAGE_INFORMATION, call->ref, &newparam);
806 }
807
808 /*
809  * new asterisk instance
810  */
811 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
812 {
813         /* create call instance */
814         call = alloc_call();
815         if (!call)
816         {
817                 /* failed to create instance */
818                 return NULL;
819         }
820         /* create asterisk channel instrance */
821         ast = ast_channel_alloc(1);
822         if (!ast)
823         {
824                 free_call(call);
825                 /* failed to create instance */
826                 return NULL;
827         }
828         /* link together */
829         ast->tech_pvt = call;
830         call->ast = ast;
831         /* send MESSAGE_NEWREF */
832         memset(&newparam, 0, sizeof(union parameter));
833         newparam.direction = 0; /* request from app */
834         send_message(MESSAGE_NEWREF, 0, &newparam);
835         /* set state */
836         call->state = CHAN_LCR_STATE_OUT_PREPARE;
837 }
838
839 /*
840  * call from asterisk
841  */
842 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
843 {
844         struct lcr_pvt *lcr=ast->tech_pvt;
845
846         if (!lcr) return -1;
847
848         char buf[128];
849         char *port_str, *dad, *p;
850
851         hier muss noch
852         ast_copy_string(buf, dest, sizeof(buf)-1);
853         p=buf;
854         port_str=strsep(&p, "/");
855         dad=strsep(&p, "/");
856
857         /* send setup message, if we already have a callref */
858         if (call->ref)
859                 send_setup_to_lcr(call);
860
861         if (lcr_debug)
862                 ast_verbose("Call: ext:%s dest:(%s) -> dad(%s) \n", ast->exten,dest, dad);
863
864
865         return 0; 
866 }
867
868 static int lcr_digit(struct ast_channel *ast, char digit)
869 {
870         char buf[]="x";
871
872         /* only pass IA5 number space */
873         if (digit > 126 || digit < 32)
874                 return 0;
875
876         /* send information or queue them */
877         if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING)
878         {
879                 send_dialing_to_lcr(call);
880         } else
881         if (!call->ref
882          && (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP));
883         {
884                 *buf = digit;
885                 strncat(call->dialque, buf, strlen(char->dialque)-1);
886         } else
887         {
888 digits kommen, koennen aber nicht verwendet werden.
889         sollen wir sie als info senden (im connect zb.)
890         }
891 }
892
893 static int lcr_answer(struct ast_channel *c)
894 {
895         struct lcr_pvt *lcr=c->tech_pvt;
896         return 0;
897 }
898
899 static int lcr_hangup(struct ast_channel *ast)
900 {
901         struct chan_call *call = ast->tech_pvt;
902
903         /* disconnect asterisk, maybe not required */
904         ast->tech_pvt = NULL;
905         if (ref)
906         {
907                 /* release */
908                 memset(&newparam, 0, sizeof(union parameter));
909                 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
910                 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
911                 send_message(MESSAGE_RELEASE, call->ref, &newparam);
912                 /* remove call */
913                 free_call(call);
914                 return;
915         } else
916         {
917                 /* ref is not set, due to prepare setup or release */
918                 if (call->state == CHAN_LCR_STATE_RELEASE)
919                 {
920                         /* we get the response to our release */
921                         free_call(call);
922                 } else
923                 {
924                         /* during prepare, we change to release state */
925                         call->state = CHAN_LCR_STATE_RELEASE;
926                 }
927         } 
928 }
929
930 static int lcr_write(struct ast_channel *c, struct ast_frame *f)
931 {
932         struct lcr_pvt *lcrm= c->tech_pvt;
933 }
934
935
936 static struct ast_frame *lcr_read(struct ast_channel *c)
937 {
938         struct lcr_pvt *lcr = c->tech_pvt;
939 }
940
941 static int lcr_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
942 {
943         int res = -1;
944
945         switch (cond) {
946                 case AST_CONTROL_BUSY:
947                 case AST_CONTROL_CONGESTION:
948                 case AST_CONTROL_RINGING:
949                         return -1;
950                 case -1:
951                         return 0;
952
953                 case AST_CONTROL_VIDUPDATE:
954                         res = -1;
955                         break;
956                 case AST_CONTROL_HOLD:
957                         ast_verbose(" << Console Has Been Placed on Hold >> \n");
958                         //ast_moh_start(c, data, g->mohinterpret);
959                         break;
960                 case AST_CONTROL_UNHOLD:
961                         ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
962                         //ast_moh_stop(c);
963                         break;
964
965                 default:
966                         ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
967                         return -1;
968         }
969
970         return 0;
971 }
972
973 static struct ast_channel_tech lcr_tech = {
974         .type="lcr",
975         .description="Channel driver for connecting to Linux-Call-Router",
976         .capabilities=AST_FORMAT_ALAW,
977         .requester=lcr_request,
978         .send_digit=lcr_digit,
979         .call=lcr_call,
980 //      .bridge=lcr_bridge, 
981         .hangup=lcr_hangup,
982         .answer=lcr_answer,
983         .read=lcr_read,
984         .write=lcr_write,
985         .indicate=lcr_indicate,
986 //      .fixup=lcr_fixup,
987 //      .send_text=lcr_send_text,
988         .properties=0
989 };
990
991 /*
992  * cli
993  */
994 static int lcr_show_lcr (int fd, int argc, char *argv[])
995 {
996 }
997
998 static int lcr_show_calls (int fd, int argc, char *argv[])
999 {
1000 }
1001
1002 static int lcr_reload_routing (int fd, int argc, char *argv[])
1003 {
1004 }
1005
1006 static int lcr_reload_interfaces (int fd, int argc, char *argv[])
1007 {
1008 }
1009
1010 static int lcr_port_block (int fd, int argc, char *argv[])
1011 {
1012 }
1013
1014 static int lcr_port_unblock (int fd, int argc, char *argv[])
1015 {
1016 }
1017
1018 static int lcr_port_unload (int fd, int argc, char *argv[])
1019 {
1020 }
1021
1022 static struct ast_cli_entry cli_show_lcr =
1023 { {"lcr", "show", "lcr", NULL},
1024  lcr_show_lcr,
1025  "Shows current states of LCR core",
1026  "Usage: lcr show lcr\n",
1027 };
1028
1029 static struct ast_cli_entry cli_show_calls =
1030 { {"lcr", "show", "calls", NULL},
1031  lcr_show_calls,
1032  "Shows current calls made by LCR and Asterisk",
1033  "Usage: lcr show calls\n",
1034 };
1035
1036 static struct ast_cli_entry cli_reload_routing =
1037 { {"lcr", "reload", "routing", NULL},
1038  lcr_reload_routing,
1039  "Reloads routing conf of LCR, current uncomplete calls will be disconnected",
1040  "Usage: lcr reload routing\n",
1041 };
1042
1043 static struct ast_cli_entry cli_reload_interfaces =
1044 { {"lcr", "reload", "interfaces", NULL},
1045  lcr_reload_interfaces,
1046  "Reloads interfaces conf of LCR",
1047  "Usage: lcr reload interfaces\n",
1048 };
1049
1050 static struct ast_cli_entry cli_port_block =
1051 { {"lcr", "port", "block", NULL},
1052  lcr_port_block,
1053  "Blocks LCR port for further calls",
1054  "Usage: lcr port block \"<port>\"\n",
1055 };
1056
1057 static struct ast_cli_entry cli_port_unblock =
1058 { {"lcr", "port", "unblock", NULL},
1059  lcr_port_unblock,
1060  "Unblocks or loads LCR port, port is opened my mISDN",
1061  "Usage: lcr port unblock \"<port>\"\n",
1062 };
1063
1064 static struct ast_cli_entry cli_port_unload =
1065 { {"lcr", "port", "unload", NULL},
1066  lcr_port_unload,
1067  "Unloads LCR port, port is closes by mISDN",
1068  "Usage: lcr port unload \"<port>\"\n",
1069 };
1070
1071
1072 /*
1073  * module loading and destruction
1074  */
1075 int load_module(void)
1076 {
1077 //      ast_mutex_init(&release_lock);
1078
1079 //      lcr_cfg_update_ptp();
1080
1081         if (!(lcr_sock = open_socket())) {
1082                 ast_log(LOG_ERROR, "Unable to connect\n");
1083                 lcr_sock = -1;
1084                 /* continue with closed socket */
1085         }
1086
1087         if (!bchannel_initialize()) {
1088                 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
1089                 return -1;
1090         }
1091         mISDN_created = 1;
1092
1093         if (ast_channel_register(&lcr_tech)) {
1094                 ast_log(LOG_ERROR, "Unable to register channel class\n");
1095                 return -1;
1096         }
1097  
1098 #if 0   
1099         ast_cli_register(&cli_show_lcr);
1100         ast_cli_register(&cli_show_calls);
1101
1102         ast_cli_register(&cli_reload_routing);
1103         ast_cli_register(&cli_reload_interfaces);
1104         ast_cli_register(&cli_port_block);
1105         ast_cli_register(&cli_port_unblock);
1106         ast_cli_register(&cli_port_unload);
1107   
1108         ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
1109                                  "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
1110                                  "Sets mISDN opts. and optargs\n"
1111                                  "\n"
1112                                  "The available options are:\n"
1113                                  "    d - Send display text on called phone, text is the optparam\n"
1114                                  "    n - don't detect dtmf tones on called channel\n"
1115                                  "    h - make digital outgoing call\n" 
1116                                  "    c - make crypted outgoing call, param is keyindex\n"
1117                                  "    e - perform echo cancelation on this channel,\n"
1118                                  "        takes taps as arguments (32,64,128,256)\n"
1119                                  "    s - send Non Inband DTMF as inband\n"
1120                                  "   vr - rxgain control\n"
1121                                  "   vt - txgain control\n"
1122                 );
1123
1124         
1125         lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1126
1127         chan_lcr_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
1128 =======
1129         //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1130 #endif
1131
1132         return 0;
1133 }
1134
1135 int unload_module(void)
1136 {
1137         /* First, take us out of the channel loop */
1138         ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
1139         
1140         
1141         ast_channel_unregister(&lcr_tech);
1142
1143         if (mISDN_created) {
1144                 bchannel_deinitialize();
1145                 mISDN_created = 0;
1146         }
1147
1148         if (lcr_sock >= 0) {
1149                 close(lcr_sock);
1150                 lcr_sock = -1;
1151         }
1152
1153         return 0;
1154 }
1155
1156 static int reload_module(void)
1157 {
1158 //      reload_config();
1159         return 0;
1160 }
1161
1162
1163 ast_mutex_t usecnt_lock;
1164 int usecnt;
1165
1166 int usecount(void)
1167 {
1168         int res;
1169         ast_mutex_lock(&usecnt_lock);
1170         res = usecnt;
1171         ast_mutex_unlock(&usecnt_lock);
1172         return res;
1173 }
1174
1175
1176 char *desc="Channel driver for lcr";
1177
1178 char *description(void)
1179 {
1180         return desc;
1181 }
1182
1183 char *key(void)
1184 {
1185         return ASTERISK_GPL_KEY;
1186 }
1187
1188 #define AST_MODULE "chan_lcr"
1189 AST_MODULE_INFO(ASTERISK_GPL_KEY,
1190                                 AST_MODFLAG_DEFAULT,
1191                                 "Channel driver for LCR",
1192                                 .load = load_module,
1193                                 .unload = unload_module,
1194                                 .reload = reload_module,
1195                            );
1196