9216699efd5ba1693bb0c8e7018fa7418ee02b2d
[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
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdarg.h>
35 #include <errno.h>
36 #include <sys/types.h>
37 #include <time.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <sys/ioctl.h>
41 #include <sys/socket.h>
42 #include <sys/un.h>
43 #include "extension.h"
44 #include "message.h"
45 #include "admin.h"
46 #include "cause.h"
47 #include "bchannel.h"
48 #include "chan_lcr.h"
49
50 int lcr_sock = -1;
51
52 struct admin_list {
53         struct admin_list *next;
54         struct admin_msg msg;
55 } *admin_first = NULL;
56
57 /*
58  * channel and call instances
59  */
60 struct chan_call *call_first;
61
62 struct chan_call *find_call_ref(unsigned long ref)
63 {
64         struct chan_call *call = call_first;
65
66         while(call)
67         {
68                 if (call->ref == ref)
69                         break;
70                 call = call->next;
71         }
72         return(call);
73 }
74
75 struct chan_call *find_call_handle(unsigned long handle)
76 {
77         struct chan_call *call = call_first;
78
79         while(call)
80         {
81                 if (call->bchannel_handle == handle)
82                         break;
83                 call = call->next;
84         }
85         return(call);
86 }
87
88 struct chan_call *alloc_call(void)
89 {
90         struct chan_call **callp = &call_first;
91
92         while(*callp)
93                 callp = &((*callp)->next);
94
95         *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
96         return(*callp);
97 }
98
99 void free_call(struct chan_call *call)
100 {
101         struct chan_call **temp = &call_first;
102
103         while(*temp)
104         {
105                 if (*temp == call)
106                 {
107                         *temp = (*temp)->next;
108                         free(call);
109                         return;
110                 }
111                 temp = &((*temp)->next);
112         }
113 }
114
115
116 /*
117  * receive bchannel data
118  */
119 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
120 {
121 }
122
123 void rx_dtmf(struct bchannel *bchannel, char tone)
124 {
125 }
126
127 /*
128  * enque message to LCR
129  */
130 int send_message(int message_type, unsigned long ref, union parameter *param)
131 {
132         struct admin_list *admin, **adminp;
133
134         adminp = &admin_first;
135         while(*adminp)
136                 adminp = &((*adminp)->next);
137         admin = (struct admin_list *)malloc(sizeof(struct admin_list));
138         *adminp = admin;
139
140         admin->msg.type = message_type;
141         admin->msg.ref = ref;
142         memcpy(&admin->msg.param, param, sizeof(union parameter));
143
144         return(0);
145 }
146
147 /*
148  * message received from LCR
149  */
150 int receive_message(int message_type, unsigned long ref, union parameter *param)
151 {
152         union parameter newparam;
153         struct bchannel *bchannel;
154         struct chan_call *call;
155
156         memset(&newparam, 0, sizeof(union parameter));
157
158         /* handle bchannel message*/
159         if (message_type == MESSAGE_BCHANNEL)
160         {
161                 switch(param->bchannel.type)
162                 {
163                         case BCHANNEL_ASSIGN:
164                         if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
165                         {
166                                 fprintf(stderr, "error: bchannel handle %x already assigned.\n", param->bchannel.handle);
167                                 return(-1);
168                         }
169                         /* create bchannel */
170                         bchannel = alloc_bchannel(param->bchannel.handle);
171                         if (!bchannel)
172                         {
173                                 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", param->bchannel.handle);
174                                 return(-1);
175                         }
176
177                         /* configure channel */
178                         bchannel->b_tx_gain = param->bchannel.tx_gain;
179                         bchannel->b_rx_gain = param->bchannel.rx_gain;
180                         strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
181                         if (param->bchannel.crypt_len)
182                         {
183                                 bchannel->b_crypt_len = param->bchannel.crypt_len;
184                                 bchannel->b_crypt_type = param->bchannel.crypt_type;
185                                 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
186                         }
187                         bchannel->b_txdata = 0;
188                         bchannel->b_dtmf = 1;
189                         bchannel->b_tx_dejitter = 1;
190
191                         /* in case, ref is not set, this bchannel instance must
192                          * be created until it is removed again by LCR */
193                         /* link to call */
194                         if ((call = find_call_ref(ref)))
195                         {
196                                 bchannel->ref = ref;
197                                 call->bchannel_handle = param->bchannel.handle;
198                         }
199                         if (bchannel_create(bchannel))
200                                 bchannel_activate(bchannel, 1);
201
202                         /* acknowledge */
203                         newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
204                         newparam.bchannel.handle = param->bchannel.handle;
205                         send_message(MESSAGE_BCHANNEL, 0, &newparam);
206                         break;
207
208                         case BCHANNEL_REMOVE:
209                         if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
210                         {
211                                 alle fprintf nach ast_log
212                                 fprintf(stderr, "error: bchannel handle %x not assigned.\n", param->bchannel.handle);
213                                 return(-1);
214                         }
215                         /* unlink from call */
216                         if ((call = find_call_ref(bchannel->ref)))
217                         {
218                                 call->bchannel_handle = 0;
219                         }
220                         /* destroy and remove bchannel */
221                         free_bchannel(bchannel);
222
223                         /* acknowledge */
224                         newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
225                         newparam.bchannel.handle = param->bchannel.handle;
226                         send_message(MESSAGE_BCHANNEL, 0, &newparam);
227                         
228                         break;
229
230                         default:
231                         fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
232                 }
233                 return(0);
234         }
235
236         /* handle new ref */
237         if (message_type == MESSAGE_NEWREF)
238         {
239                 if (param->direction)
240                 {
241                         /* new ref from lcr */
242                         if (!ref || find_call_ref(ref))
243                         {
244                                 fprintf(stderr, "illegal new ref %d received\n", ref);
245                                 return(-1);
246                         }
247                         call = alloc_call();
248                         call->ref = ref;
249                 } else
250                 {
251                         /* new ref, as requested from this remote application */
252                         call = find_call_ref(0);
253                         if (!call)
254                         {
255                                 /* send release, if ref does not exist */
256                                 newparam.disconnectinfo.cause = CAUSE_NORMAL;
257                                 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
258                                 send_message(MESSAGE_RELEASE, ref, &newparam);
259                                 return(0);
260                         }
261                         call->ref = ref;
262 #warning process call (send setup, if pending)
263                 }
264                 return(0);
265         }
266
267         /* check ref */
268         if (!ref)
269         {
270                 fprintf(stderr, "received message %d without ref\n", message_type);
271                 return(-1);
272         }
273         call = find_call_ref(ref);
274         if (!call)
275         {
276                 /* ignore ref that is not used (anymore) */
277                 return(0);
278         }
279
280         /* handle messages */
281         switch(message_type)
282         {
283                 case MESSAGE_SETUP:
284 todo
285                 break;
286
287                 case MESSAGE_OVERLAP:
288 todo
289                 break;
290
291                 case MESSAGE_PROCEEDING:
292 todo
293                 break;
294
295                 case MESSAGE_ALERTING:
296 todo
297                 break;
298
299                 case MESSAGE_CONNECT:
300 todo
301                 break;
302
303                 case MESSAGE_DISCONNECT:
304 todo
305                 break;
306
307                 case MESSAGE_RELEASE:
308 todo
309                 free_call(call);
310                 return(0);
311
312                 case MESSAGE_INFORMATION:
313 todo
314                 break;
315
316                 case MESSAGE_FACILITY:
317 todo
318                 break;
319
320                 case MESSAGE_PATTERN:
321 todo
322                 break;
323
324                 case MESSAGE_NOPATTERN:
325 todo
326                 break;
327
328                 case MESSAGE_AUDIOPATH:
329 todo
330                 break;
331
332                 default:
333 unhandled
334         }
335         return(0);
336 }
337
338
339 /* asterisk handler
340  * warning! not thread safe
341  * returns -1 for socket error, 0 for no work, 1 for work
342  */
343 int handle_socket(void)
344 {
345         int work = 0;
346         int len;
347         struct admin_message msg;
348         struct admin_list *admin;
349
350         /* read from socket */
351         len = read(sock, &msg, sizeof(msg));
352         if (len == 0)
353         {
354                 printf("Socket closed\n");
355                 return(-1); // socket closed
356         }
357         if (len > 0)
358         {
359                 if (len != sizeof(msg))
360                 {
361                         fprintf(stderr, "Socket short read (%d)\n", len);
362                         return(-1); // socket error
363                 }
364                 if (msg.message != ADMIN_MESSAGE)
365                 {
366                         fprintf(stderr, "Socket received illegal message %d\n", msg.message);
367                         return(-1); // socket error
368                 }
369                 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
370                 printf("message received %d\n", msg.u.msg.type);
371                 work = 1;
372         } else
373         {
374                 if (errno != EWOULDBLOCK)
375                 {
376                         fprintf(stderr, "Socket error %d\n", errno);
377                         return(-1);
378                 }
379         }
380
381         /* write to socket */
382         if (!admin_first)
383                 return(work);
384         admin = admin_first;
385         len = write(sock, &admin->msg, sizeof(msg));
386         if (len == 0)
387         {
388                 printf("Socket closed\n");
389                 return(-1); // socket closed
390         }
391         if (len > 0)
392         {
393                 if (len != sizeof(msg))
394                 {
395                         fprintf(stderr, "Socket short write (%d)\n", len);
396                         return(-1); // socket error
397                 }
398                 /* free head */
399                 admin_first = admin->next;
400                 free(admin);
401
402                 work = 1;
403         } else
404         {
405                 if (errno != EWOULDBLOCK)
406                 {
407                         fprintf(stderr, "Socket error %d\n", errno);
408                         return(-1);
409                 }
410         }
411
412         return(work);
413 }
414
415 /*
416  * open and close socket
417  */
418 int open_socket(void)
419 {
420         int ret;
421         int sock;
422         char *socket_name = SOCKET_NAME;
423         int conn;
424         struct sockaddr_un sock_address;
425         int ret;
426         unsigned long on = 1;
427         union parameter param;
428
429         /* open socket */
430         if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
431         {
432                 ast_log(LOG_ERROR, "Failed to create socket.\n");
433                 return(sock);
434         }
435
436         /* set socket address and name */
437         memset(&sock_address, 0, sizeof(sock_address));
438         sock_address.sun_family = PF_UNIX;
439         strcpy(sock_address.sun_path, socket_name);
440
441         /* connect socket */
442         if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
443         {
444                 close(sock);
445                 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
446                 return(conn);
447         }
448
449         /* set non-blocking io */
450         if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
451         {
452                 close(sock);
453                 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
454                 return(ret);
455         }
456
457         /* enque hello message */
458         memset(&param, 0, sizeof(param));
459         strcpy(param.hello.application, "asterisk");
460         send_message(MESSAGE_HELLO, 0, &param);
461
462         return(sock);
463 }
464
465 void close_socket(int sock)
466 {
467         /* close socket */
468         if (socket >= 0)        
469                 close(sock);
470 }
471
472
473 void lcr_thread(void)
474 {
475         int work;
476
477         while(42)
478         {
479                 work = 0;
480
481                 /* handle socket */
482                 ret = handle_socket();
483                 if (ret < 0)
484                         break;
485                 if (ret)
486                         work = 1;
487
488                 /* handle mISDN */
489                 ret = bchannel_handle();
490                 if (ret)
491                         work = 1;
492                 
493                 if (!work)
494                         usleep(30000);
495         }
496 }
497
498 static struct ast_channel_tech misdn_tech = {
499         .type="lcr",
500         .description="Channel driver for connecting to Linux-Call-Router",
501         .capabilities= je nach option?AST_FORMAT_ALAW:AST_FORMAT_ULAW ,
502         .requester=lcr_request,
503         .send_digit=lcr_digit,
504         .call=lcr_call,
505         .bridge=lcr_bridge, 
506         .hangup=lcr_hangup,
507         .answer=lcr_answer,
508         .read=lcr_read,
509         .write=lcr_write,
510         .indicate=lcr_indication,
511         .fixup=lcr_fixup,
512         .send_text=lcr_send_text,
513         .properties=0
514 };
515
516
517 /*
518  * module loading and destruction
519  */
520 int load_module(void)
521 {
522 //      ast_mutex_init(&release_lock);
523
524 //      lcr_cfg_update_ptp();
525
526         if (!(lcr_sock = open_socket())) {
527                 ast_log(LOG_ERROR, "Unable to connect %s\n", misdn_type);
528                 lcr_sock = -1;
529                 /* continue with closed socket */
530         }
531
532         if (!bchannel_initialize()) {
533                 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
534                 unload_module();
535                 return -1;
536         }
537         mISDN_created = 1;
538
539         if (ast_channel_register(&lcr_tech)) {
540                 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
541                 unload_module();
542                 return -1;
543         }
544   
545         ast_cli_register(&cli_show_cls);
546         ast_cli_register(&cli_show_cl);
547         ast_cli_register(&cli_show_config);
548
549         ast_cli_register(&cli_reload);
550
551   
552         ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
553                                  "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
554                                  "Sets mISDN opts. and optargs\n"
555                                  "\n"
556                                  "The available options are:\n"
557                                  "    d - Send display text on called phone, text is the optparam\n"
558                                  "    n - don't detect dtmf tones on called channel\n"
559                                  "    h - make digital outgoing call\n" 
560                                  "    c - make crypted outgoing call, param is keyindex\n"
561                                  "    e - perform echo cancelation on this channel,\n"
562                                  "        takes taps as arguments (32,64,128,256)\n"
563                                  "    s - send Non Inband DTMF as inband\n"
564                                  "   vr - rxgain control\n"
565                                  "   vt - txgain control\n"
566                 );
567
568         
569         lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
570
571         chan_lcr_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
572
573         return 0;
574 }
575
576 int unload_module(void)
577 {
578         /* First, take us out of the channel loop */
579         ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
580         
581         misdn_tasks_destroy();
582         
583         if (!g_config_initialized) return 0;
584         
585         ast_cli_unregister(&cli_show_cls);
586         ast_cli_unregister(&cli_show_cl);
587         ast_cli_unregister(&cli_show_config);
588         ast_cli_unregister(&cli_reload);
589         ast_unregister_application("misdn_set_opt");
590   
591         ast_channel_unregister(&lcr_tech);
592
593         if (mISDN_created) {
594                 bchannel_deinitialize();
595                 mISDN_created = 0;
596         }
597
598         if (lcr_sock >= 0) {
599                 close(lcr_sock);
600                 lcr_sock = -1;
601         }
602
603         was ist mit dem mutex
604         
605         return 0;
606 }
607
608 int reload(void)
609 {
610         reload_config();
611
612         return 0;
613 }
614
615 int usecount(void)
616 {
617         int res;
618         ast_mutex_lock(&usecnt_lock);
619         res = usecnt;
620         ast_mutex_unlock(&usecnt_lock);
621         return res;
622 }
623
624 char *description(void)
625 {
626         return desc;
627 }
628
629 char *key(void)
630 {
631         return ASTERISK_GPL_KEY;
632 }
633
634