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