0234e4ce7e1ef702662a1556a67bd5a43d60fdc5
[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 How does it work:
15
16 To connect, open a socket and send a MESSAGE_HELLO to admin socket with
17 the application name. This name is unique an can be used for routing calls.
18
19 To make a call, send a MESSAGE_NEWREF and a new reference is received.
20 When receiving a call, a new reference is received.
21 The reference is received with MESSAGE_NEWREF.
22
23 Make a MESSAGE_SETUP or receive a MESSAGE_SETUP with the reference.
24
25 To release call and reference, send or receive MESSAGE_RELEASE.
26 From that point on, the ref is not valid, so no other message may be sent
27 with that reference.
28
29 */
30 bchannel-handling muss noch
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <stdarg.h>
36 #include <errno.h>
37 #include <sys/types.h>
38 #include <time.h>
39 #include <unistd.h>
40 #include <fcntl.h>
41 #include <sys/ioctl.h>
42 #include <sys/socket.h>
43 #include <sys/un.h>
44 #include "extension.h"
45 #include "message.h"
46 #include "lcrsocket.h"
47 #include "cause.h"
48 #include "bchannel.h"
49 #include "chan_lcr.h"
50
51 int lcr_sock = -1;
52
53 struct admin_list {
54         struct admin_list *next;
55         struct admin_msg msg;
56 } *admin_first = NULL;
57
58 /*
59  * channel and call instances
60  */
61 struct chan_call *call_first;
62
63 struct chan_call *find_call_ref(unsigned long ref)
64 {
65         struct chan_call *call = call_first;
66
67         while(call)
68         {
69                 if (call->ref == ref)
70                         break;
71                 call = call->next;
72         }
73         return(call);
74 }
75
76 struct chan_call *find_call_handle(unsigned long handle)
77 {
78         struct chan_call *call = call_first;
79
80         while(call)
81         {
82                 if (call->bchannel_handle == handle)
83                         break;
84                 call = call->next;
85         }
86         return(call);
87 }
88
89 struct chan_call *alloc_call(void)
90 {
91         struct chan_call **callp = &call_first;
92
93         while(*callp)
94                 callp = &((*callp)->next);
95
96         *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
97         return(*callp);
98 }
99
100 void free_call(struct chan_call *call)
101 {
102         struct chan_call **temp = &call_first;
103
104         while(*temp)
105         {
106                 if (*temp == call)
107                 {
108                         *temp = (*temp)->next;
109                         free(call);
110                         return;
111                 }
112                 temp = &((*temp)->next);
113         }
114 }
115
116 unsigned short new_brige_id(void)
117 {
118         struct chan_call *call;
119         unsigned short id = 1;
120
121         /* search for lowest bridge id that is not in use and not 0 */
122         while(id)
123         {
124                 call = call_first;
125                 while(call)
126                 {
127                         if (call->bridge_id == id)
128                                 break;
129                         call = call->next;
130                 }
131                 if (!call)
132                         break;
133                 id++;
134         }
135         return(id);
136 }
137
138
139 /*
140  * receive bchannel data
141  */
142 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
143 {
144 }
145
146 void rx_dtmf(struct bchannel *bchannel, char tone)
147 {
148 }
149
150 /*
151  * enque message to LCR
152  */
153 int send_message(int message_type, unsigned long ref, union parameter *param)
154 {
155         struct admin_list *admin, **adminp;
156
157         adminp = &admin_first;
158         while(*adminp)
159                 adminp = &((*adminp)->next);
160         admin = (struct admin_list *)malloc(sizeof(struct admin_list));
161         *adminp = admin;
162
163         admin->msg.type = message_type;
164         admin->msg.ref = ref;
165         memcpy(&admin->msg.param, param, sizeof(union parameter));
166
167         return(0);
168 }
169
170 /*
171  * message received from LCR
172  */
173 int receive_message(int message_type, unsigned long ref, union parameter *param)
174 {
175         union parameter newparam;
176         struct bchannel *bchannel;
177         struct chan_call *call;
178
179         memset(&newparam, 0, sizeof(union parameter));
180
181         /* handle bchannel message*/
182         if (message_type == MESSAGE_BCHANNEL)
183         {
184                 switch(param->bchannel.type)
185                 {
186                         case BCHANNEL_ASSIGN:
187                         if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
188                         {
189                                 fprintf(stderr, "error: bchannel handle %x already assigned.\n", param->bchannel.handle);
190                                 return(-1);
191                         }
192                         /* create bchannel */
193                         bchannel = alloc_bchannel(param->bchannel.handle);
194                         if (!bchannel)
195                         {
196                                 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", param->bchannel.handle);
197                                 return(-1);
198                         }
199
200                         /* configure channel */
201                         bchannel->b_tx_gain = param->bchannel.tx_gain;
202                         bchannel->b_rx_gain = param->bchannel.rx_gain;
203                         strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
204                         if (param->bchannel.crypt_len)
205                         {
206                                 bchannel->b_crypt_len = param->bchannel.crypt_len;
207                                 bchannel->b_crypt_type = param->bchannel.crypt_type;
208                                 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
209                         }
210                         bchannel->b_txdata = 0;
211                         bchannel->b_dtmf = 1;
212                         bchannel->b_tx_dejitter = 1;
213
214                         /* in case, ref is not set, this bchannel instance must
215                          * be created until it is removed again by LCR */
216                         /* link to call */
217                         if ((call = find_call_ref(ref)))
218                         {
219                                 bchannel->ref = ref;
220                                 call->bchannel_handle = param->bchannel.handle;
221 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
222                                 bchannel_join(call->bridge_id);
223                         }
224                         if (bchannel_create(bchannel))
225                                 bchannel_activate(bchannel, 1);
226
227                         /* acknowledge */
228                         newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
229                         newparam.bchannel.handle = param->bchannel.handle;
230                         send_message(MESSAGE_BCHANNEL, 0, &newparam);
231                         break;
232
233                         case BCHANNEL_REMOVE:
234                         if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
235                         {
236                                 alle fprintf nach ast_log
237                                 fprintf(stderr, "error: bchannel handle %x not assigned.\n", param->bchannel.handle);
238                                 return(-1);
239                         }
240                         /* unlink from call */
241                         if ((call = find_call_ref(bchannel->ref)))
242                         {
243                                 call->bchannel_handle = 0;
244                         }
245                         /* destroy and remove bchannel */
246                         free_bchannel(bchannel);
247
248                         /* acknowledge */
249                         newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
250                         newparam.bchannel.handle = param->bchannel.handle;
251                         send_message(MESSAGE_BCHANNEL, 0, &newparam);
252                         
253                         break;
254
255                         default:
256                         fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
257                 }
258                 return(0);
259         }
260
261         /* handle new ref */
262         if (message_type == MESSAGE_NEWREF)
263         {
264                 if (param->direction)
265                 {
266                         /* new ref from lcr */
267                         if (!ref || find_call_ref(ref))
268                         {
269                                 fprintf(stderr, "illegal new ref %d received\n", ref);
270                                 return(-1);
271                         }
272                         call = alloc_call();
273                         call->ref = ref;
274                 } else
275                 {
276                         /* new ref, as requested from this remote application */
277                         call = find_call_ref(0);
278                         if (!call)
279                         {
280                                 /* send release, if ref does not exist */
281                                 newparam.disconnectinfo.cause = CAUSE_NORMAL;
282                                 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
283                                 send_message(MESSAGE_RELEASE, ref, &newparam);
284                                 return(0);
285                         }
286                         call->ref = ref;
287 #warning process call (send setup, if pending)
288                 }
289                 return(0);
290         }
291
292         /* check ref */
293         if (!ref)
294         {
295                 fprintf(stderr, "received message %d without ref\n", message_type);
296                 return(-1);
297         }
298         call = find_call_ref(ref);
299         if (!call)
300         {
301                 /* ignore ref that is not used (anymore) */
302                 return(0);
303         }
304
305         /* handle messages */
306         switch(message_type)
307         {
308                 case MESSAGE_SETUP:
309 todo
310                 break;
311
312                 case MESSAGE_OVERLAP:
313 todo
314                 break;
315
316                 case MESSAGE_PROCEEDING:
317 todo
318                 break;
319
320                 case MESSAGE_ALERTING:
321 todo
322                 break;
323
324                 case MESSAGE_CONNECT:
325 todo
326                 break;
327
328                 case MESSAGE_DISCONNECT:
329 todo
330                 break;
331
332                 case MESSAGE_RELEASE:
333 todo
334                 free_call(call);
335                 return(0);
336
337                 case MESSAGE_INFORMATION:
338 todo
339                 break;
340
341                 case MESSAGE_FACILITY:
342 todo
343                 break;
344
345                 case MESSAGE_PATTERN:
346 todo
347                 break;
348
349                 case MESSAGE_NOPATTERN:
350 todo
351                 break;
352
353                 case MESSAGE_AUDIOPATH:
354 todo
355                 break;
356
357                 default:
358 unhandled
359         }
360         return(0);
361 }
362
363
364 /* asterisk handler
365  * warning! not thread safe
366  * returns -1 for socket error, 0 for no work, 1 for work
367  */
368 int handle_socket(void)
369 {
370         int work = 0;
371         int len;
372         struct admin_message msg;
373         struct admin_list *admin;
374
375         /* read from socket */
376         len = read(sock, &msg, sizeof(msg));
377         if (len == 0)
378         {
379                 printf("Socket closed\n");
380                 return(-1); // socket closed
381         }
382         if (len > 0)
383         {
384                 if (len != sizeof(msg))
385                 {
386                         fprintf(stderr, "Socket short read (%d)\n", len);
387                         return(-1); // socket error
388                 }
389                 if (msg.message != ADMIN_MESSAGE)
390                 {
391                         fprintf(stderr, "Socket received illegal message %d\n", msg.message);
392                         return(-1); // socket error
393                 }
394                 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
395                 printf("message received %d\n", msg.u.msg.type);
396                 work = 1;
397         } else
398         {
399                 if (errno != EWOULDBLOCK)
400                 {
401                         fprintf(stderr, "Socket error %d\n", errno);
402                         return(-1);
403                 }
404         }
405
406         /* write to socket */
407         if (!admin_first)
408                 return(work);
409         admin = admin_first;
410         len = write(sock, &admin->msg, sizeof(msg));
411         if (len == 0)
412         {
413                 printf("Socket closed\n");
414                 return(-1); // socket closed
415         }
416         if (len > 0)
417         {
418                 if (len != sizeof(msg))
419                 {
420                         fprintf(stderr, "Socket short write (%d)\n", len);
421                         return(-1); // socket error
422                 }
423                 /* free head */
424                 admin_first = admin->next;
425                 free(admin);
426
427                 work = 1;
428         } else
429         {
430                 if (errno != EWOULDBLOCK)
431                 {
432                         fprintf(stderr, "Socket error %d\n", errno);
433                         return(-1);
434                 }
435         }
436
437         return(work);
438 }
439
440 /*
441  * open and close socket
442  */
443 int open_socket(void)
444 {
445         int ret;
446         int sock;
447         char *socket_name = SOCKET_NAME;
448         int conn;
449         struct sockaddr_un sock_address;
450         int ret;
451         unsigned long on = 1;
452         union parameter param;
453
454         /* open socket */
455         if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
456         {
457                 ast_log(LOG_ERROR, "Failed to create socket.\n");
458                 return(sock);
459         }
460
461         /* set socket address and name */
462         memset(&sock_address, 0, sizeof(sock_address));
463         sock_address.sun_family = PF_UNIX;
464         strcpy(sock_address.sun_path, socket_name);
465
466         /* connect socket */
467         if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
468         {
469                 close(sock);
470                 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
471                 return(conn);
472         }
473
474         /* set non-blocking io */
475         if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
476         {
477                 close(sock);
478                 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
479                 return(ret);
480         }
481
482         /* enque hello message */
483         memset(&param, 0, sizeof(param));
484         strcpy(param.hello.application, "asterisk");
485         send_message(MESSAGE_HELLO, 0, &param);
486
487         return(sock);
488 }
489
490 void close_socket(int sock)
491 {
492         /* close socket */
493         if (socket >= 0)        
494                 close(sock);
495 }
496
497
498 void lcr_thread(void)
499 {
500         int work;
501
502         while(42)
503         {
504                 work = 0;
505
506                 /* handle socket */
507                 ret = handle_socket();
508                 if (ret < 0)
509                         break;
510                 if (ret)
511                         work = 1;
512
513                 /* handle mISDN */
514                 ret = bchannel_handle();
515                 if (ret)
516                         work = 1;
517                 
518                 if (!work)
519                         usleep(30000);
520         }
521 }
522
523 /* call from asterisk (new instance) */
524 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
525 {
526         int port=0;
527         int r;
528         struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
529         struct misdn_bchannel *newbc;
530         char *opts=NULL, *ext;
531         char dest_cp[256];
532         
533         {
534                 strncpy(dest_cp,dest,sizeof(dest_cp)-1);
535                 dest_cp[sizeof(dest_cp)]=0;
536
537                 ext=dest_cp;
538                 strsep(&ext,"/");
539                 if (ext) {
540                         opts=ext;
541                         strsep(&opts,"/");
542                 }  else {
543                         ast_log(LOG_WARNING, "Malformed dialstring\n");
544                         return -1;
545                 }
546         }
547
548         if (!ast) {
549                 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
550                 return -1;
551         }
552
553         if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest  ) {
554                 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
555                 ast->hangupcause=41;
556                 ast_setstate(ast, AST_STATE_DOWN);
557                 return -1;
558         }
559
560         if (!ch) {
561                 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
562                 ast->hangupcause=41;
563                 ast_setstate(ast, AST_STATE_DOWN);
564                 return -1;
565         }
566         
567         newbc=ch->bc;
568         
569         if (!newbc) {
570                 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
571                 ast->hangupcause=41;
572                 ast_setstate(ast, AST_STATE_DOWN);
573                 return -1;
574         }
575         
576         port=newbc->port;
577
578         
579         chan_misdn_log(1, port, "* CALL: %s\n",dest);
580         
581         chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context);
582         
583         chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten);
584         if (ast->exten) {
585                 int l = sizeof(newbc->dad);
586                 strncpy(ast->exten,ext,sizeof(ast->exten));
587
588                 strncpy(newbc->dad,ext,l);
589
590                 newbc->dad[l-1] = 0;
591         }
592         newbc->rad[0]=0;
593         chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n",AST_CID_P(ast));
594         if (ast_strlen_zero(newbc->oad) && AST_CID_P(ast) ) {
595
596                 if (AST_CID_P(ast)) {
597                         int l = sizeof(newbc->oad);
598                         strncpy(newbc->oad,AST_CID_P(ast), l);
599                         newbc->oad[l-1] = 0;
600                 }
601         }
602
603         {
604                 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
605                 if (!ch) { ast_verbose("No chan_list in misdn_call\n"); return -1;}
606                 
607                 newbc->capability=ast->transfercapability;
608                 pbx_builtin_setvar_helper(ast,"TRANSFERCAPABILITY",ast_transfercapability2str(newbc->capability));
609                 if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) {
610                         chan_misdn_log(2, port, " --> * Call with flag Digital\n");
611                 }
612                 
613
614                 /* update screening and presentation */ 
615                 update_config(ch,ORG_AST);
616                 
617                 /* fill in some ies from channel vary*/
618                 import_ch(ast, newbc, ch);
619                 
620                 /* Finally The Options Override Everything */
621                 if (opts)
622                         misdn_set_opt_exec(ast,opts);
623                 else
624                         chan_misdn_log(2,port,"NO OPTS GIVEN\n");
625
626                 /*check for bridging*/
627                 int bridging;
628                 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
629                 if (bridging && ch->other_ch) {
630                         chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n");
631                         *ch->bc->pipeline=0;
632                         *ch->other_ch->bc->pipeline=0;
633                 }
634                 
635                 r=misdn_lib_send_event( newbc, EVENT_SETUP );
636                 
637                 /** we should have l3id after sending setup **/
638                 ch->l3id=newbc->l3_id;
639         }
640         
641         if ( r == -ENOCHAN  ) {
642                 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
643                 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n",newbc?newbc->pid:-1);
644                 ast->hangupcause=34;
645                 ast_setstate(ast, AST_STATE_DOWN);
646                 return -1;
647         }
648         
649         chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1);
650
651         ast_setstate(ast, AST_STATE_DIALING);
652         ast->hangupcause=16;
653
654 wenn pattern available soll gestoppt werden, sonst nicht:       
655         if (newbc->nt) stop_bc_tones(ch);
656
657         ch->state=MISDN_CALLING;
658         
659         return 0; 
660 }
661
662
663 static struct ast_channel_tech misdn_tech = {
664         .type="lcr",
665         .description="Channel driver for connecting to Linux-Call-Router",
666         .capabilities= je nach option?AST_FORMAT_ALAW:AST_FORMAT_ULAW ,
667         .requester=lcr_request,
668         .send_digit=lcr_digit,
669         .call=lcr_call,
670         .bridge=lcr_bridge, 
671         .hangup=lcr_hangup,
672         .answer=lcr_answer,
673         .read=lcr_read,
674         .write=lcr_write,
675         .indicate=lcr_indication,
676         .fixup=lcr_fixup,
677         .send_text=lcr_send_text,
678         .properties=0
679 };
680
681
682 /*
683  * module loading and destruction
684  */
685 int load_module(void)
686 {
687 //      ast_mutex_init(&release_lock);
688
689 //      lcr_cfg_update_ptp();
690
691         if (!(lcr_sock = open_socket())) {
692                 ast_log(LOG_ERROR, "Unable to connect %s\n", misdn_type);
693                 lcr_sock = -1;
694                 /* continue with closed socket */
695         }
696
697         if (!bchannel_initialize()) {
698                 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
699                 unload_module();
700                 return -1;
701         }
702         mISDN_created = 1;
703
704         if (ast_channel_register(&lcr_tech)) {
705                 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
706                 unload_module();
707                 return -1;
708         }
709   
710         ast_cli_register(&cli_show_lcr);
711         ast_cli_register(&cli_show_calls);
712
713         ast_cli_register(&cli_reload_routing);
714         ast_cli_register(&cli_reload_interfaces);
715         ast_cli_register(&cli_port_block);
716         ast_cli_register(&cli_port_unblock);
717   
718         ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
719                                  "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
720                                  "Sets mISDN opts. and optargs\n"
721                                  "\n"
722                                  "The available options are:\n"
723                                  "    d - Send display text on called phone, text is the optparam\n"
724                                  "    n - don't detect dtmf tones on called channel\n"
725                                  "    h - make digital outgoing call\n" 
726                                  "    c - make crypted outgoing call, param is keyindex\n"
727                                  "    e - perform echo cancelation on this channel,\n"
728                                  "        takes taps as arguments (32,64,128,256)\n"
729                                  "    s - send Non Inband DTMF as inband\n"
730                                  "   vr - rxgain control\n"
731                                  "   vt - txgain control\n"
732                 );
733
734         
735         lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
736
737         chan_lcr_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
738
739         return 0;
740 }
741
742 int unload_module(void)
743 {
744         /* First, take us out of the channel loop */
745         ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
746         
747         misdn_tasks_destroy();
748         
749         if (!g_config_initialized) return 0;
750         
751         ast_cli_unregister(&cli_show_lcr);
752         ast_cli_unregister(&cli_show_calls);
753         ast_cli_unregister(&cli_reload_routing);
754         ast_cli_unregister(&cli_reload_interfaces);
755         ast_cli_unregister(&cli_port_block);
756         ast_cli_unregister(&cli_port_unblock);
757         ast_unregister_application("misdn_set_opt");
758   
759         ast_channel_unregister(&lcr_tech);
760
761         if (mISDN_created) {
762                 bchannel_deinitialize();
763                 mISDN_created = 0;
764         }
765
766         if (lcr_sock >= 0) {
767                 close(lcr_sock);
768                 lcr_sock = -1;
769         }
770
771         was ist mit dem mutex
772         
773         return 0;
774 }
775
776 int reload(void)
777 {
778         reload_config();
779
780         return 0;
781 }
782
783 int usecount(void)
784 {
785         int res;
786         ast_mutex_lock(&usecnt_lock);
787         res = usecnt;
788         ast_mutex_unlock(&usecnt_lock);
789         return res;
790 }
791
792 char *description(void)
793 {
794         return desc;
795 }
796
797 char *key(void)
798 {
799         return ASTERISK_GPL_KEY;
800 }
801
802