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