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>
43 #include "extension.h"
45 #include "lcrsocket.h"
53 struct admin_list *next;
55 } *admin_first = NULL;
58 * channel and call instances
60 struct chan_call *call_first;
62 struct chan_call *find_call_ref(unsigned long ref)
64 struct chan_call *call = call_first;
75 struct chan_call *find_call_handle(unsigned long handle)
77 struct chan_call *call = call_first;
81 if (call->bchannel_handle == handle)
88 struct chan_call *alloc_call(void)
90 struct chan_call **callp = &call_first;
93 callp = &((*callp)->next);
95 *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
99 void free_call(struct chan_call *call)
101 struct chan_call **temp = &call_first;
107 *temp = (*temp)->next;
111 temp = &((*temp)->next);
115 unsigned short new_brige_id(void)
117 struct chan_call *call;
118 unsigned short id = 1;
120 /* search for lowest bridge id that is not in use and not 0 */
126 if (call->bridge_id == id)
139 * receive bchannel data
141 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
145 void rx_dtmf(struct bchannel *bchannel, char tone)
150 * enque message to LCR
152 int send_message(int message_type, unsigned long ref, union parameter *param)
154 struct admin_list *admin, **adminp;
156 adminp = &admin_first;
158 adminp = &((*adminp)->next);
159 admin = (struct admin_list *)malloc(sizeof(struct admin_list));
162 admin->msg.type = message_type;
163 admin->msg.ref = ref;
164 memcpy(&admin->msg.param, param, sizeof(union parameter));
170 * message received from LCR
172 int receive_message(int message_type, unsigned long ref, union parameter *param)
174 union parameter newparam;
175 struct bchannel *bchannel;
176 struct chan_call *call;
178 memset(&newparam, 0, sizeof(union parameter));
180 /* handle bchannel message*/
181 if (message_type == MESSAGE_BCHANNEL)
183 switch(param->bchannel.type)
185 case BCHANNEL_ASSIGN:
186 if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
188 fprintf(stderr, "error: bchannel handle %x already assigned.\n", param->bchannel.handle);
191 /* create bchannel */
192 bchannel = alloc_bchannel(param->bchannel.handle);
195 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", param->bchannel.handle);
199 /* configure channel */
200 bchannel->b_tx_gain = param->bchannel.tx_gain;
201 bchannel->b_rx_gain = param->bchannel.rx_gain;
202 strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
203 if (param->bchannel.crypt_len)
205 bchannel->b_crypt_len = param->bchannel.crypt_len;
206 bchannel->b_crypt_type = param->bchannel.crypt_type;
207 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
209 bchannel->b_txdata = 0;
210 bchannel->b_dtmf = 1;
211 bchannel->b_tx_dejitter = 1;
213 /* in case, ref is not set, this bchannel instance must
214 * be created until it is removed again by LCR */
216 if ((call = find_call_ref(ref)))
219 call->bchannel_handle = param->bchannel.handle;
220 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
221 bchannel_join(call->bridge_id);
223 if (bchannel_create(bchannel))
224 bchannel_activate(bchannel, 1);
227 newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
228 newparam.bchannel.handle = param->bchannel.handle;
229 send_message(MESSAGE_BCHANNEL, 0, &newparam);
232 case BCHANNEL_REMOVE:
233 if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
235 alle fprintf nach ast_log
236 fprintf(stderr, "error: bchannel handle %x not assigned.\n", param->bchannel.handle);
239 /* unlink from call */
240 if ((call = find_call_ref(bchannel->ref)))
242 call->bchannel_handle = 0;
244 /* destroy and remove bchannel */
245 free_bchannel(bchannel);
248 newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
249 newparam.bchannel.handle = param->bchannel.handle;
250 send_message(MESSAGE_BCHANNEL, 0, &newparam);
255 fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
261 if (message_type == MESSAGE_NEWREF)
263 if (param->direction)
265 /* new ref from lcr */
266 if (!ref || find_call_ref(ref))
268 fprintf(stderr, "illegal new ref %d received\n", ref);
275 /* new ref, as requested from this remote application */
276 call = find_call_ref(0);
279 /* send release, if ref does not exist */
280 newparam.disconnectinfo.cause = CAUSE_NORMAL;
281 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
282 send_message(MESSAGE_RELEASE, ref, &newparam);
286 #warning process call (send setup, if pending)
294 fprintf(stderr, "received message %d without ref\n", message_type);
297 call = find_call_ref(ref);
300 /* ignore ref that is not used (anymore) */
304 /* handle messages */
311 case MESSAGE_OVERLAP:
315 case MESSAGE_PROCEEDING:
319 case MESSAGE_ALERTING:
323 case MESSAGE_CONNECT:
327 case MESSAGE_DISCONNECT:
331 case MESSAGE_RELEASE:
336 case MESSAGE_INFORMATION:
340 case MESSAGE_FACILITY:
344 case MESSAGE_PATTERN:
348 case MESSAGE_NOPATTERN:
352 case MESSAGE_AUDIOPATH:
364 * warning! not thread safe
365 * returns -1 for socket error, 0 for no work, 1 for work
367 int handle_socket(void)
371 struct admin_message msg;
372 struct admin_list *admin;
374 /* read from socket */
375 len = read(sock, &msg, sizeof(msg));
378 printf("Socket closed\n");
379 return(-1); // socket closed
383 if (len != sizeof(msg))
385 fprintf(stderr, "Socket short read (%d)\n", len);
386 return(-1); // socket error
388 if (msg.message != ADMIN_MESSAGE)
390 fprintf(stderr, "Socket received illegal message %d\n", msg.message);
391 return(-1); // socket error
393 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
394 printf("message received %d\n", msg.u.msg.type);
398 if (errno != EWOULDBLOCK)
400 fprintf(stderr, "Socket error %d\n", errno);
405 /* write to socket */
409 len = write(sock, &admin->msg, sizeof(msg));
412 printf("Socket closed\n");
413 return(-1); // socket closed
417 if (len != sizeof(msg))
419 fprintf(stderr, "Socket short write (%d)\n", len);
420 return(-1); // socket error
423 admin_first = admin->next;
429 if (errno != EWOULDBLOCK)
431 fprintf(stderr, "Socket error %d\n", errno);
440 * open and close socket
442 int open_socket(void)
446 char *socket_name = SOCKET_NAME;
448 struct sockaddr_un sock_address;
450 unsigned long on = 1;
451 union parameter param;
454 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
456 ast_log(LOG_ERROR, "Failed to create socket.\n");
460 /* set socket address and name */
461 memset(&sock_address, 0, sizeof(sock_address));
462 sock_address.sun_family = PF_UNIX;
463 strcpy(sock_address.sun_path, socket_name);
466 if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
469 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
473 /* set non-blocking io */
474 if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
477 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
481 /* enque hello message */
482 memset(¶m, 0, sizeof(param));
483 strcpy(param.hello.application, "asterisk");
484 send_message(MESSAGE_HELLO, 0, ¶m);
489 void close_socket(int sock)
497 void lcr_thread(void)
506 ret = handle_socket();
513 ret = bchannel_handle();
522 /* call from asterisk (new instance) */
523 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
527 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
528 struct misdn_bchannel *newbc;
529 char *opts=NULL, *ext;
533 strncpy(dest_cp,dest,sizeof(dest_cp)-1);
534 dest_cp[sizeof(dest_cp)]=0;
542 ast_log(LOG_WARNING, "Malformed dialstring\n");
548 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
552 if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest ) {
553 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
555 ast_setstate(ast, AST_STATE_DOWN);
560 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
562 ast_setstate(ast, AST_STATE_DOWN);
569 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
571 ast_setstate(ast, AST_STATE_DOWN);
578 chan_misdn_log(1, port, "* CALL: %s\n",dest);
580 chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context);
582 chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten);
584 int l = sizeof(newbc->dad);
585 strncpy(ast->exten,ext,sizeof(ast->exten));
587 strncpy(newbc->dad,ext,l);
592 chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n",AST_CID_P(ast));
593 if (ast_strlen_zero(newbc->oad) && AST_CID_P(ast) ) {
595 if (AST_CID_P(ast)) {
596 int l = sizeof(newbc->oad);
597 strncpy(newbc->oad,AST_CID_P(ast), l);
603 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
604 if (!ch) { ast_verbose("No chan_list in misdn_call\n"); return -1;}
606 newbc->capability=ast->transfercapability;
607 pbx_builtin_setvar_helper(ast,"TRANSFERCAPABILITY",ast_transfercapability2str(newbc->capability));
608 if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) {
609 chan_misdn_log(2, port, " --> * Call with flag Digital\n");
613 /* update screening and presentation */
614 update_config(ch,ORG_AST);
616 /* fill in some ies from channel vary*/
617 import_ch(ast, newbc, ch);
619 /* Finally The Options Override Everything */
621 misdn_set_opt_exec(ast,opts);
623 chan_misdn_log(2,port,"NO OPTS GIVEN\n");
625 /*check for bridging*/
627 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
628 if (bridging && ch->other_ch) {
629 chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n");
631 *ch->other_ch->bc->pipeline=0;
634 r=misdn_lib_send_event( newbc, EVENT_SETUP );
636 /** we should have l3id after sending setup **/
637 ch->l3id=newbc->l3_id;
640 if ( r == -ENOCHAN ) {
641 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
642 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n",newbc?newbc->pid:-1);
644 ast_setstate(ast, AST_STATE_DOWN);
648 chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1);
650 ast_setstate(ast, AST_STATE_DIALING);
653 wenn pattern available soll gestoppt werden, sonst nicht:
654 if (newbc->nt) stop_bc_tones(ch);
656 ch->state=MISDN_CALLING;
662 static struct ast_channel_tech misdn_tech = {
664 .description="Channel driver for connecting to Linux-Call-Router",
665 .capabilities= je nach option?AST_FORMAT_ALAW:AST_FORMAT_ULAW ,
666 .requester=lcr_request,
667 .send_digit=lcr_digit,
674 .indicate=lcr_indication,
676 .send_text=lcr_send_text,
682 * module loading and destruction
684 int load_module(void)
686 // ast_mutex_init(&release_lock);
688 // lcr_cfg_update_ptp();
690 if (!(lcr_sock = open_socket())) {
691 ast_log(LOG_ERROR, "Unable to connect %s\n", misdn_type);
693 /* continue with closed socket */
696 if (!bchannel_initialize()) {
697 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
703 if (ast_channel_register(&lcr_tech)) {
704 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
709 ast_cli_register(&cli_show_lcr);
710 ast_cli_register(&cli_show_calls);
712 ast_cli_register(&cli_reload_routing);
713 ast_cli_register(&cli_reload_interfaces);
714 ast_cli_register(&cli_port_block);
715 ast_cli_register(&cli_port_unblock);
717 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
718 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
719 "Sets mISDN opts. and optargs\n"
721 "The available options are:\n"
722 " d - Send display text on called phone, text is the optparam\n"
723 " n - don't detect dtmf tones on called channel\n"
724 " h - make digital outgoing call\n"
725 " c - make crypted outgoing call, param is keyindex\n"
726 " e - perform echo cancelation on this channel,\n"
727 " takes taps as arguments (32,64,128,256)\n"
728 " s - send Non Inband DTMF as inband\n"
729 " vr - rxgain control\n"
730 " vt - txgain control\n"
734 lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
736 chan_lcr_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
741 int unload_module(void)
743 /* First, take us out of the channel loop */
744 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
746 misdn_tasks_destroy();
748 if (!g_config_initialized) return 0;
750 ast_cli_unregister(&cli_show_lcr);
751 ast_cli_unregister(&cli_show_calls);
752 ast_cli_unregister(&cli_reload_routing);
753 ast_cli_unregister(&cli_reload_interfaces);
754 ast_cli_unregister(&cli_port_block);
755 ast_cli_unregister(&cli_port_unblock);
756 ast_unregister_application("misdn_set_opt");
758 ast_channel_unregister(&lcr_tech);
761 bchannel_deinitialize();
770 was ist mit dem mutex
785 ast_mutex_lock(&usecnt_lock);
787 ast_mutex_unlock(&usecnt_lock);
791 char *description(void)
798 return ASTERISK_GPL_KEY;