chan_lcr.c compiles now, and the Makefile generates a .so instead of an executable.
[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
44 #include <pthread.h>
45 #include <semaphore.h>
46
47 #include "extension.h"
48 #include "message.h"
49 #include "lcrsocket.h"
50 #include "cause.h"
51 #include "bchannel.h"
52 #include "chan_lcr.h"
53
54
55
56 #include <asterisk/module.h>
57 #include <asterisk/channel.h>
58 #include <asterisk/config.h>
59 #include <asterisk/logger.h>
60 #include <asterisk/pbx.h>
61 #include <asterisk/options.h>
62 #include <asterisk/io.h>
63 #include <asterisk/frame.h>
64 #include <asterisk/translate.h>
65 #include <asterisk/cli.h>
66 #include <asterisk/musiconhold.h>
67 #include <asterisk/dsp.h>
68 #include <asterisk/translate.h>
69 #include <asterisk/file.h>
70 #include <asterisk/callerid.h>
71 #include <asterisk/indications.h>
72 #include <asterisk/app.h>
73 #include <asterisk/features.h>
74 #include <asterisk/sched.h>
75
76 int lcr_debug=1;
77 int mISDN_created=1;
78
79
80 int lcr_sock = -1;
81
82 struct admin_list {
83         struct admin_list *next;
84         struct admin_msg msg;
85 } *admin_first = NULL;
86
87 /*
88  * channel and call instances
89  */
90 struct chan_call *call_first;
91
92 struct chan_call *find_call_ref(unsigned long ref)
93 {
94         struct chan_call *call = call_first;
95
96         while(call)
97         {
98                 if (call->ref == ref)
99                         break;
100                 call = call->next;
101         }
102         return(call);
103 }
104
105 struct chan_call *find_call_handle(unsigned long handle)
106 {
107         struct chan_call *call = call_first;
108
109         while(call)
110         {
111                 if (call->bchannel_handle == handle)
112                         break;
113                 call = call->next;
114         }
115         return(call);
116 }
117
118 struct chan_call *alloc_call(void)
119 {
120         struct chan_call **callp = &call_first;
121
122         while(*callp)
123                 callp = &((*callp)->next);
124
125         *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
126         return(*callp);
127 }
128
129 void free_call(struct chan_call *call)
130 {
131         struct chan_call **temp = &call_first;
132
133         while(*temp)
134         {
135                 if (*temp == call)
136                 {
137                         *temp = (*temp)->next;
138                         free(call);
139                         return;
140                 }
141                 temp = &((*temp)->next);
142         }
143 }
144
145 unsigned short new_brige_id(void)
146 {
147         struct chan_call *call;
148         unsigned short id = 1;
149
150         /* search for lowest bridge id that is not in use and not 0 */
151         while(id)
152         {
153                 call = call_first;
154                 while(call)
155                 {
156                         if (call->bridge_id == id)
157                                 break;
158                         call = call->next;
159                 }
160                 if (!call)
161                         break;
162                 id++;
163         }
164         return(id);
165 }
166
167
168 /*
169  * receive bchannel data
170  */
171 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
172 {
173 }
174
175 void rx_dtmf(struct bchannel *bchannel, char tone)
176 {
177 }
178
179 /*
180  * enque message to LCR
181  */
182 int send_message(int message_type, unsigned long ref, union parameter *param)
183 {
184         struct admin_list *admin, **adminp;
185
186         adminp = &admin_first;
187         while(*adminp)
188                 adminp = &((*adminp)->next);
189         admin = (struct admin_list *)malloc(sizeof(struct admin_list));
190         *adminp = admin;
191
192         admin->msg.type = message_type;
193         admin->msg.ref = ref;
194         memcpy(&admin->msg.param, param, sizeof(union parameter));
195
196         return(0);
197 }
198
199 /*
200  * message received from LCR
201  */
202 int receive_message(int message_type, unsigned long ref, union parameter *param)
203 {
204         union parameter newparam;
205         struct bchannel *bchannel;
206         struct chan_call *call;
207
208         memset(&newparam, 0, sizeof(union parameter));
209
210         /* handle bchannel message*/
211         if (message_type == MESSAGE_BCHANNEL)
212         {
213                 switch(param->bchannel.type)
214                 {
215                         case BCHANNEL_ASSIGN:
216                         if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
217                         {
218                                 fprintf(stderr, "error: bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
219                                 return(-1);
220                         }
221                         /* create bchannel */
222                         bchannel = alloc_bchannel(param->bchannel.handle);
223                         if (!bchannel)
224                         {
225                                 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
226                                 return(-1);
227                         }
228
229                         /* configure channel */
230                         bchannel->b_tx_gain = param->bchannel.tx_gain;
231                         bchannel->b_rx_gain = param->bchannel.rx_gain;
232                         strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
233                         if (param->bchannel.crypt_len)
234                         {
235                                 bchannel->b_crypt_len = param->bchannel.crypt_len;
236                                 bchannel->b_crypt_type = param->bchannel.crypt_type;
237                                 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
238                         }
239                         bchannel->b_txdata = 0;
240                         bchannel->b_dtmf = 1;
241                         bchannel->b_tx_dejitter = 1;
242
243                         /* in case, ref is not set, this bchannel instance must
244                          * be created until it is removed again by LCR */
245                         /* link to call */
246                         if ((call = find_call_ref(ref)))
247                         {
248                                 bchannel->ref = ref;
249                                 call->bchannel_handle = param->bchannel.handle;
250 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
251                                 bchannel_join(bchannel, call->bridge_id);
252                         }
253                         if (bchannel_create(bchannel))
254                                 bchannel_activate(bchannel, 1);
255
256                         /* acknowledge */
257                         newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
258                         newparam.bchannel.handle = param->bchannel.handle;
259                         send_message(MESSAGE_BCHANNEL, 0, &newparam);
260                         break;
261
262                         case BCHANNEL_REMOVE:
263                         if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
264                         {
265                                 #warning alle fprintf nach ast_log
266                                 fprintf(stderr, "error: bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
267                                 return(-1);
268                         }
269                         /* unlink from call */
270                         if ((call = find_call_ref(bchannel->ref)))
271                         {
272                                 call->bchannel_handle = 0;
273                         }
274                         /* destroy and remove bchannel */
275                         free_bchannel(bchannel);
276
277                         /* acknowledge */
278                         newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
279                         newparam.bchannel.handle = param->bchannel.handle;
280                         send_message(MESSAGE_BCHANNEL, 0, &newparam);
281                         
282                         break;
283
284                         default:
285                         fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
286                 }
287                 return(0);
288         }
289
290         /* handle new ref */
291         if (message_type == MESSAGE_NEWREF)
292         {
293                 if (param->direction)
294                 {
295                         /* new ref from lcr */
296                         if (!ref || find_call_ref(ref))
297                         {
298                                 fprintf(stderr, "illegal new ref %d received\n", ref);
299                                 return(-1);
300                         }
301                         call = alloc_call();
302                         call->ref = ref;
303                 } else
304                 {
305                         /* new ref, as requested from this remote application */
306                         call = find_call_ref(0);
307                         if (!call)
308                         {
309                                 /* send release, if ref does not exist */
310                                 newparam.disconnectinfo.cause = CAUSE_NORMAL;
311                                 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
312                                 send_message(MESSAGE_RELEASE, ref, &newparam);
313                                 return(0);
314                         }
315                         call->ref = ref;
316 #warning process call (send setup, if pending)
317                 }
318                 return(0);
319         }
320
321         /* check ref */
322         if (!ref)
323         {
324                 fprintf(stderr, "received message %d without ref\n", message_type);
325                 return(-1);
326         }
327         call = find_call_ref(ref);
328         if (!call)
329         {
330                 /* ignore ref that is not used (anymore) */
331                 return(0);
332         }
333
334         /* handle messages */
335         switch(message_type)
336         {
337                 case MESSAGE_SETUP:
338 #warning todo
339                 break;
340
341                 case MESSAGE_OVERLAP:
342 #warning todo
343                 break;
344
345                 case MESSAGE_PROCEEDING:
346 #warning todo
347                 break;
348
349                 case MESSAGE_ALERTING:
350 #warning todo
351                 break;
352
353                 case MESSAGE_CONNECT:
354 #warning todo
355                 break;
356
357                 case MESSAGE_DISCONNECT:
358 #warning todo
359                 break;
360
361                 case MESSAGE_RELEASE:
362 #warning todo
363                 free_call(call);
364                 return(0);
365
366                 case MESSAGE_INFORMATION:
367 #warning todo
368                 break;
369
370                 case MESSAGE_FACILITY:
371 #warning todo
372                 break;
373
374                 case MESSAGE_PATTERN:
375 #warning todo
376                 break;
377
378                 case MESSAGE_NOPATTERN:
379 #warning todo
380                 break;
381
382                 case MESSAGE_AUDIOPATH:
383 #warning todo
384                 break;
385
386                 default:
387 #warning unhandled
388         }
389         return(0);
390 }
391
392
393 /* asterisk handler
394  * warning! not thread safe
395  * returns -1 for socket error, 0 for no work, 1 for work
396  */
397 int handle_socket(void)
398 {
399         int work = 0;
400         int len;
401         struct admin_message msg;
402         struct admin_list *admin;
403
404         int sock;
405
406         #warning SOCKET FEHLT!
407         /* read from socket */
408         len = read(sock, &msg, sizeof(msg));
409         if (len == 0)
410         {
411                 printf("Socket closed\n");
412                 return(-1); // socket closed
413         }
414         if (len > 0)
415         {
416                 if (len != sizeof(msg))
417                 {
418                         fprintf(stderr, "Socket short read (%d)\n", len);
419                         return(-1); // socket error
420                 }
421                 if (msg.message != ADMIN_MESSAGE)
422                 {
423                         fprintf(stderr, "Socket received illegal message %d\n", msg.message);
424                         return(-1); // socket error
425                 }
426                 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
427                 printf("message received %d\n", msg.u.msg.type);
428                 work = 1;
429         } else
430         {
431                 if (errno != EWOULDBLOCK)
432                 {
433                         fprintf(stderr, "Socket error %d\n", errno);
434                         return(-1);
435                 }
436         }
437
438         /* write to socket */
439         if (!admin_first)
440                 return(work);
441         admin = admin_first;
442         len = write(sock, &admin->msg, sizeof(msg));
443         if (len == 0)
444         {
445                 printf("Socket closed\n");
446                 return(-1); // socket closed
447         }
448         if (len > 0)
449         {
450                 if (len != sizeof(msg))
451                 {
452                         fprintf(stderr, "Socket short write (%d)\n", len);
453                         return(-1); // socket error
454                 }
455                 /* free head */
456                 admin_first = admin->next;
457                 free(admin);
458
459                 work = 1;
460         } else
461         {
462                 if (errno != EWOULDBLOCK)
463                 {
464                         fprintf(stderr, "Socket error %d\n", errno);
465                         return(-1);
466                 }
467         }
468
469         return(work);
470 }
471
472 /*
473  * open and close socket
474  */
475 int open_socket(void)
476 {
477         int ret;
478         int sock;
479         char *socket_name = SOCKET_NAME;
480         int conn;
481         struct sockaddr_un sock_address;
482         unsigned long on = 1;
483         union parameter param;
484
485         /* open socket */
486         if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
487         {
488                 ast_log(LOG_ERROR, "Failed to create socket.\n");
489                 return(sock);
490         }
491
492         /* set socket address and name */
493         memset(&sock_address, 0, sizeof(sock_address));
494         sock_address.sun_family = PF_UNIX;
495         strcpy(sock_address.sun_path, socket_name);
496
497         /* connect socket */
498         if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
499         {
500                 close(sock);
501                 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
502                 return(conn);
503         }
504
505         /* set non-blocking io */
506         if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
507         {
508                 close(sock);
509                 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
510                 return(ret);
511         }
512
513         /* enque hello message */
514         memset(&param, 0, sizeof(param));
515         strcpy(param.hello.application, "asterisk");
516         send_message(MESSAGE_HELLO, 0, &param);
517
518         return(sock);
519 }
520
521 void close_socket(int sock)
522 {
523         /* close socket */
524         if (socket >= 0)        
525                 close(sock);
526 }
527
528
529 void lcr_thread(void)
530 {
531         int work;
532
533         while(42)
534         {
535                 work = 0;
536
537                 /* handle socket */
538                 int ret = handle_socket();
539                 if (ret < 0)
540                         break;
541                 if (ret)
542                         work = 1;
543
544                 /* handle mISDN */
545                 ret = bchannel_handle();
546                 if (ret)
547                         work = 1;
548                 
549                 if (!work)
550                         usleep(30000);
551         }
552 }
553
554 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
555 {
556
557 }
558
559
560 /* call from asterisk (new instance) */
561 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
562 {
563         struct lcr_pvt *lcr=ast->tech_pvt;
564
565         if (!lcr) return -1;
566
567         char buf[128];
568         char *port_str, *dad, *p;
569
570         ast_copy_string(buf, dest, sizeof(buf)-1);
571         p=buf;
572         port_str=strsep(&p, "/");
573         dad=strsep(&p, "/");
574
575         if (lcr_debug)
576                 ast_verbose("Call: ext:%s dest:(%s) -> dad(%s) \n", ast->exten,dest, dad);
577
578
579         return 0; 
580 }
581
582 static int lcr_answer(struct ast_channel *c)
583 {
584         struct lcr_pvt *lcr=c->tech_pvt;
585         return 0;
586 }
587
588 static int lcr_hangup(struct ast_channel *c)
589 {
590         struct lcr_pvt *lcr=c->tech_pvt;
591         c->tech_pvt=NULL;
592 }
593
594
595 static int lcr_write(struct ast_channel *c, struct ast_frame *f)
596 {
597         struct lcr_pvt *lcrm= c->tech_pvt;
598 }
599
600
601 static struct ast_frame *lcr_read(struct ast_channel *c)
602 {
603         struct lcr_pvt *lcr = c->tech_pvt;
604 }
605
606 static int lcr_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
607 {
608         int res = -1;
609
610         switch (cond) {
611                 case AST_CONTROL_BUSY:
612                 case AST_CONTROL_CONGESTION:
613                 case AST_CONTROL_RINGING:
614                         return -1;
615                 case -1:
616                         return 0;
617
618                 case AST_CONTROL_VIDUPDATE:
619                         res = -1;
620                         break;
621                 case AST_CONTROL_HOLD:
622                         ast_verbose(" << Console Has Been Placed on Hold >> \n");
623                         //ast_moh_start(c, data, g->mohinterpret);
624                         break;
625                 case AST_CONTROL_UNHOLD:
626                         ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
627                         //ast_moh_stop(c);
628                         break;
629
630                 default:
631                         ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
632                         return -1;
633         }
634
635         return 0;
636 }
637
638 static struct ast_channel_tech lcr_tech = {
639         .type="lcr",
640         .description="Channel driver for connecting to Linux-Call-Router",
641         .capabilities=AST_FORMAT_ALAW,
642         .requester=lcr_request,
643 //      .send_digit=lcr_digit,
644         .call=lcr_call,
645 //      .bridge=lcr_bridge, 
646         .hangup=lcr_hangup,
647         .answer=lcr_answer,
648         .read=lcr_read,
649         .write=lcr_write,
650         .indicate=lcr_indicate,
651 //      .fixup=lcr_fixup,
652 //      .send_text=lcr_send_text,
653         .properties=0
654 };
655
656
657 /*
658  * module loading and destruction
659  */
660 int load_module(void)
661 {
662 //      ast_mutex_init(&release_lock);
663
664 //      lcr_cfg_update_ptp();
665
666         if (!(lcr_sock = open_socket())) {
667                 ast_log(LOG_ERROR, "Unable to connect\n");
668                 lcr_sock = -1;
669                 /* continue with closed socket */
670         }
671
672         if (!bchannel_initialize()) {
673                 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
674                 return -1;
675         }
676         mISDN_created = 1;
677
678         if (ast_channel_register(&lcr_tech)) {
679                 ast_log(LOG_ERROR, "Unable to register channel class\n");
680                 return -1;
681         }
682   
683         //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
684
685         return 0;
686 }
687
688 int unload_module(void)
689 {
690         /* First, take us out of the channel loop */
691         ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
692         
693         
694         ast_channel_unregister(&lcr_tech);
695
696         if (mISDN_created) {
697                 bchannel_deinitialize();
698                 mISDN_created = 0;
699         }
700
701         if (lcr_sock >= 0) {
702                 close(lcr_sock);
703                 lcr_sock = -1;
704         }
705
706         return 0;
707 }
708
709 static int reload_module(void)
710 {
711 //      reload_config();
712         return 0;
713 }
714
715
716 ast_mutex_t usecnt_lock;
717 int usecnt;
718
719 int usecount(void)
720 {
721         int res;
722         ast_mutex_lock(&usecnt_lock);
723         res = usecnt;
724         ast_mutex_unlock(&usecnt_lock);
725         return res;
726 }
727
728
729 char *desc="Channel driver for lcr";
730
731 char *description(void)
732 {
733         return desc;
734 }
735
736 char *key(void)
737 {
738         return ASTERISK_GPL_KEY;
739 }
740
741 #define AST_MODULE "chan_lcr"
742 AST_MODULE_INFO(ASTERISK_GPL_KEY,
743                                 AST_MODFLAG_DEFAULT,
744                                 "Channel driver for lcr",
745                                 .load = load_module,
746                                 .unload = unload_module,
747                                 .reload = reload_module,
748                            );
749