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