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