1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** Asterisk socket client **
10 \*****************************************************************************/
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.
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.
23 Make a MESSAGE_SETUP or receive a MESSAGE_SETUP with the reference.
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
36 #include <sys/types.h>
40 #include <sys/ioctl.h>
41 #include <sys/socket.h>
45 #include <semaphore.h>
47 #include "extension.h"
49 #include "lcrsocket.h"
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>
79 char lcr_type[]="LCR";
85 struct admin_list *next;
87 } *admin_first = NULL;
90 * channel and call instances
92 struct chan_call *call_first;
94 struct chan_call *find_call_ref(unsigned long ref)
96 struct chan_call *call = call_first;
100 if (call->ref == ref)
107 struct chan_call *find_call_handle(unsigned long handle)
109 struct chan_call *call = call_first;
113 if (call->bchannel_handle == handle)
120 struct chan_call *alloc_call(void)
122 struct chan_call **callp = &call_first;
125 callp = &((*callp)->next);
127 *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
131 void free_call(struct chan_call *call)
133 struct chan_call **temp = &call_first;
139 *temp = (*temp)->next;
143 temp = &((*temp)->next);
147 unsigned short new_brige_id(void)
149 struct chan_call *call;
150 unsigned short id = 1;
152 /* search for lowest bridge id that is not in use and not 0 */
158 if (call->bridge_id == id)
171 * receive bchannel data
173 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
177 void rx_dtmf(struct bchannel *bchannel, char tone)
182 * enque message to LCR
184 int send_message(int message_type, unsigned long ref, union parameter *param)
186 struct admin_list *admin, **adminp;
188 adminp = &admin_first;
190 adminp = &((*adminp)->next);
191 admin = (struct admin_list *)malloc(sizeof(struct admin_list));
194 admin->msg.type = message_type;
195 admin->msg.ref = ref;
196 memcpy(&admin->msg.param, param, sizeof(union parameter));
202 * message received from LCR
204 int receive_message(int message_type, unsigned long ref, union parameter *param)
206 union parameter newparam;
207 struct bchannel *bchannel;
208 struct chan_call *call;
210 memset(&newparam, 0, sizeof(union parameter));
212 /* handle bchannel message*/
213 if (message_type == MESSAGE_BCHANNEL)
215 switch(param->bchannel.type)
217 case BCHANNEL_ASSIGN:
218 if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
220 fprintf(stderr, "error: bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
223 /* create bchannel */
224 bchannel = alloc_bchannel(param->bchannel.handle);
227 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
231 /* configure channel */
232 bchannel->b_tx_gain = param->bchannel.tx_gain;
233 bchannel->b_rx_gain = param->bchannel.rx_gain;
234 strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
235 if (param->bchannel.crypt_len)
237 bchannel->b_crypt_len = param->bchannel.crypt_len;
238 bchannel->b_crypt_type = param->bchannel.crypt_type;
239 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
241 bchannel->b_txdata = 0;
242 bchannel->b_dtmf = 1;
243 bchannel->b_tx_dejitter = 1;
245 /* in case, ref is not set, this bchannel instance must
246 * be created until it is removed again by LCR */
248 if ((call = find_call_ref(ref)))
251 call->bchannel_handle = param->bchannel.handle;
252 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
253 bchannel_join(bchannel, call->bridge_id);
255 if (bchannel_create(bchannel))
256 bchannel_activate(bchannel, 1);
259 newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
260 newparam.bchannel.handle = param->bchannel.handle;
261 send_message(MESSAGE_BCHANNEL, 0, &newparam);
264 case BCHANNEL_REMOVE:
265 if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
267 #warning alle fprintf nach ast_log
268 fprintf(stderr, "error: bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
271 /* unlink from call */
272 if ((call = find_call_ref(bchannel->ref)))
274 call->bchannel_handle = 0;
276 /* destroy and remove bchannel */
277 free_bchannel(bchannel);
280 newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
281 newparam.bchannel.handle = param->bchannel.handle;
282 send_message(MESSAGE_BCHANNEL, 0, &newparam);
287 fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
293 if (message_type == MESSAGE_NEWREF)
295 if (param->direction)
297 /* new ref from lcr */
298 if (!ref || find_call_ref(ref))
300 fprintf(stderr, "illegal new ref %d received\n", ref);
307 /* new ref, as requested from this remote application */
308 call = find_call_ref(0);
311 /* send release, if ref does not exist */
312 newparam.disconnectinfo.cause = CAUSE_NORMAL;
313 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
314 send_message(MESSAGE_RELEASE, ref, &newparam);
318 #warning process call (send setup, if pending)
326 fprintf(stderr, "received message %d without ref\n", message_type);
329 call = find_call_ref(ref);
332 /* ignore ref that is not used (anymore) */
336 /* handle messages */
343 case MESSAGE_OVERLAP:
347 case MESSAGE_PROCEEDING:
351 case MESSAGE_ALERTING:
355 case MESSAGE_CONNECT:
359 case MESSAGE_DISCONNECT:
363 case MESSAGE_RELEASE:
368 case MESSAGE_INFORMATION:
372 case MESSAGE_FACILITY:
376 case MESSAGE_PATTERN:
380 case MESSAGE_NOPATTERN:
384 case MESSAGE_AUDIOPATH:
396 * warning! not thread safe
397 * returns -1 for socket error, 0 for no work, 1 for work
399 int handle_socket(void)
403 struct admin_message msg;
404 struct admin_list *admin;
408 #warning SOCKET FEHLT!
409 /* read from socket */
410 len = read(sock, &msg, sizeof(msg));
413 printf("Socket closed\n");
414 return(-1); // socket closed
418 if (len != sizeof(msg))
420 fprintf(stderr, "Socket short read (%d)\n", len);
421 return(-1); // socket error
423 if (msg.message != ADMIN_MESSAGE)
425 fprintf(stderr, "Socket received illegal message %d\n", msg.message);
426 return(-1); // socket error
428 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
429 printf("message received %d\n", msg.u.msg.type);
433 if (errno != EWOULDBLOCK)
435 fprintf(stderr, "Socket error %d\n", errno);
440 /* write to socket */
444 len = write(sock, &admin->msg, sizeof(msg));
447 printf("Socket closed\n");
448 return(-1); // socket closed
452 if (len != sizeof(msg))
454 fprintf(stderr, "Socket short write (%d)\n", len);
455 return(-1); // socket error
458 admin_first = admin->next;
464 if (errno != EWOULDBLOCK)
466 fprintf(stderr, "Socket error %d\n", errno);
475 * open and close socket
477 int open_socket(void)
481 char *socket_name = SOCKET_NAME;
483 struct sockaddr_un sock_address;
484 unsigned long on = 1;
485 union parameter param;
488 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
490 ast_log(LOG_ERROR, "Failed to create socket.\n");
494 /* set socket address and name */
495 memset(&sock_address, 0, sizeof(sock_address));
496 sock_address.sun_family = PF_UNIX;
497 strcpy(sock_address.sun_path, socket_name);
500 if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
503 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
507 /* set non-blocking io */
508 if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
511 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
515 /* enque hello message */
516 memset(¶m, 0, sizeof(param));
517 strcpy(param.hello.application, "asterisk");
518 send_message(MESSAGE_HELLO, 0, ¶m);
523 void close_socket(int sock)
531 void lcr_thread(void)
540 int ret = handle_socket();
547 ret = bchannel_handle();
557 static struct ast_channel *lcr_ast_new(struct chan_call *call, char *exten, char *callerid, int ref);
559 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
561 struct ast_channel *ast=NULL;
564 char *port_str, *ext, *p;
567 ast_copy_string(buf, data, sizeof(buf)-1);
569 port_str=strsep(&p, "/");
571 ast_verbose("portstr:%s ext:%s\n",port_str, ext);
573 sprintf(buf,"%s/%s",lcr_type,(char*)data);
575 struct chan_call *call=alloc_call();
578 #warning hier muss jetzt wohl eine Ref angefordert werden!
579 ast=lcr_ast_new(call, ext, NULL, 0 );
584 ast_log(LOG_WARNING, "Could not create new Asterisk Channel\n");
588 ast_log(LOG_WARNING, "Could not create new Lcr Call Handle\n");
595 /* call from asterisk (new instance) */
596 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
598 struct chan_call *call=ast->tech_pvt;
600 if (!call) return -1;
603 char *port_str, *dad, *p;
605 ast_copy_string(buf, dest, sizeof(buf)-1);
607 port_str=strsep(&p, "/");
611 ast_verbose("Call: ext:%s dest:(%s) -> dad(%s) \n", ast->exten,dest, dad);
613 #warning hier müssen wi eine der geholten REFs nehmen und ein SETUP schicken, die INFOS zum SETUP stehen im Ast pointer drin, bzw. werden hier übergeben.
618 static int lcr_answer(struct ast_channel *c)
620 struct chan_call *call=c->tech_pvt;
624 static int lcr_hangup(struct ast_channel *c)
626 struct chan_call *call=c->tech_pvt;
631 static int lcr_write(struct ast_channel *c, struct ast_frame *f)
633 struct chan_call *callm= c->tech_pvt;
637 static struct ast_frame *lcr_read(struct ast_channel *c)
639 struct chan_call *call = c->tech_pvt;
642 static int lcr_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
647 case AST_CONTROL_BUSY:
648 case AST_CONTROL_CONGESTION:
649 case AST_CONTROL_RINGING:
654 case AST_CONTROL_VIDUPDATE:
657 case AST_CONTROL_HOLD:
658 ast_verbose(" << Console Has Been Placed on Hold >> \n");
659 //ast_moh_start(c, data, g->mohinterpret);
661 case AST_CONTROL_UNHOLD:
662 ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
667 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
674 static struct ast_channel_tech lcr_tech = {
676 .description="Channel driver for connecting to Linux-Call-Router",
677 .capabilities=AST_FORMAT_ALAW,
678 .requester=lcr_request,
679 // .send_digit=lcr_digit,
681 // .bridge=lcr_bridge,
686 .indicate=lcr_indicate,
688 // .send_text=lcr_send_text,
692 #warning das muss mal aus der config datei gelesen werden:
693 char lcr_context[]="from-lcr";
695 static struct ast_channel *lcr_ast_new(struct chan_call *call, char *exten, char *callerid, int ref)
697 struct ast_channel *tmp;
698 char *cid_name = 0, *cid_num = 0;
702 ast_callerid_parse(callerid, &cid_name, &cid_num);
704 tmp = ast_channel_alloc(1, AST_STATE_RESERVED, cid_num, cid_name, "", exten, "", 0, "%s/%d", lcr_type, ref);
707 tmp->tech = &lcr_tech;
708 tmp->writeformat = AST_FORMAT_ALAW;
709 tmp->readformat = AST_FORMAT_ALAW;
711 ast_copy_string(tmp->context, lcr_context, AST_MAX_CONTEXT);
723 static int lcr_show_lcr (int fd, int argc, char *argv[])
727 static int lcr_show_calls (int fd, int argc, char *argv[])
731 static int lcr_reload_routing (int fd, int argc, char *argv[])
735 static int lcr_reload_interfaces (int fd, int argc, char *argv[])
739 static int lcr_port_block (int fd, int argc, char *argv[])
743 static int lcr_port_unblock (int fd, int argc, char *argv[])
747 static int lcr_port_unload (int fd, int argc, char *argv[])
751 static struct ast_cli_entry cli_show_lcr =
752 { {"lcr", "show", "lcr", NULL},
754 "Shows current states of LCR core",
755 "Usage: lcr show lcr\n",
758 static struct ast_cli_entry cli_show_calls =
759 { {"lcr", "show", "calls", NULL},
761 "Shows current calls made by LCR and Asterisk",
762 "Usage: lcr show calls\n",
765 static struct ast_cli_entry cli_reload_routing =
766 { {"lcr", "reload", "routing", NULL},
768 "Reloads routing conf of LCR, current uncomplete calls will be disconnected",
769 "Usage: lcr reload routing\n",
772 static struct ast_cli_entry cli_reload_interfaces =
773 { {"lcr", "reload", "interfaces", NULL},
774 lcr_reload_interfaces,
775 "Reloads interfaces conf of LCR",
776 "Usage: lcr reload interfaces\n",
779 static struct ast_cli_entry cli_port_block =
780 { {"lcr", "port", "block", NULL},
782 "Blocks LCR port for further calls",
783 "Usage: lcr port block \"<port>\"\n",
786 static struct ast_cli_entry cli_port_unblock =
787 { {"lcr", "port", "unblock", NULL},
789 "Unblocks or loads LCR port, port is opened my mISDN",
790 "Usage: lcr port unblock \"<port>\"\n",
793 static struct ast_cli_entry cli_port_unload =
794 { {"lcr", "port", "unload", NULL},
796 "Unloads LCR port, port is closes by mISDN",
797 "Usage: lcr port unload \"<port>\"\n",
802 * module loading and destruction
804 int load_module(void)
806 // ast_mutex_init(&release_lock);
808 // lcr_cfg_update_ptp();
810 if (!(lcr_sock = open_socket())) {
811 ast_log(LOG_ERROR, "Unable to connect\n");
813 /* continue with closed socket */
816 if (!bchannel_initialize()) {
817 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
822 if (ast_channel_register(&lcr_tech)) {
823 ast_log(LOG_ERROR, "Unable to register channel class\n");
828 ast_cli_register(&cli_show_lcr);
829 ast_cli_register(&cli_show_calls);
831 ast_cli_register(&cli_reload_routing);
832 ast_cli_register(&cli_reload_interfaces);
833 ast_cli_register(&cli_port_block);
834 ast_cli_register(&cli_port_unblock);
835 ast_cli_register(&cli_port_unload);
837 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
838 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
839 "Sets mISDN opts. and optargs\n"
841 "The available options are:\n"
842 " d - Send display text on called phone, text is the optparam\n"
843 " n - don't detect dtmf tones on called channel\n"
844 " h - make digital outgoing call\n"
845 " c - make crypted outgoing call, param is keyindex\n"
846 " e - perform echo cancelation on this channel,\n"
847 " takes taps as arguments (32,64,128,256)\n"
848 " s - send Non Inband DTMF as inband\n"
849 " vr - rxgain control\n"
850 " vt - txgain control\n"
854 lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
856 chan_lcr_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
858 //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
864 int unload_module(void)
866 /* First, take us out of the channel loop */
867 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
870 ast_channel_unregister(&lcr_tech);
873 bchannel_deinitialize();
885 static int reload_module(void)
892 ast_mutex_t usecnt_lock;
898 ast_mutex_lock(&usecnt_lock);
900 ast_mutex_unlock(&usecnt_lock);
905 char *desc="Channel driver for lcr";
907 char *description(void)
914 return ASTERISK_GPL_KEY;
917 #define AST_MODULE "chan_lcr"
918 AST_MODULE_INFO(ASTERISK_GPL_KEY,
920 "Channel driver for lcr",
922 .unload = unload_module,
923 .reload = reload_module,