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
30 bchannel-handling muss noch
37 #include <sys/types.h>
41 #include <sys/ioctl.h>
42 #include <sys/socket.h>
44 #include "extension.h"
46 #include "lcrsocket.h"
54 struct admin_list *next;
56 } *admin_first = NULL;
59 * channel and call instances
61 struct chan_call *call_first;
63 struct chan_call *find_call_ref(unsigned long ref)
65 struct chan_call *call = call_first;
76 struct chan_call *find_call_handle(unsigned long handle)
78 struct chan_call *call = call_first;
82 if (call->bchannel_handle == handle)
89 struct chan_call *alloc_call(void)
91 struct chan_call **callp = &call_first;
94 callp = &((*callp)->next);
96 *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
100 void free_call(struct chan_call *call)
102 struct chan_call **temp = &call_first;
108 *temp = (*temp)->next;
112 temp = &((*temp)->next);
116 unsigned short new_brige_id(void)
118 struct chan_call *call;
119 unsigned short id = 1;
121 /* search for lowest bridge id that is not in use and not 0 */
127 if (call->bridge_id == id)
140 * receive bchannel data
142 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
146 void rx_dtmf(struct bchannel *bchannel, char tone)
151 * enque message to LCR
153 int send_message(int message_type, unsigned long ref, union parameter *param)
155 struct admin_list *admin, **adminp;
157 adminp = &admin_first;
159 adminp = &((*adminp)->next);
160 admin = (struct admin_list *)malloc(sizeof(struct admin_list));
163 admin->msg.type = message_type;
164 admin->msg.ref = ref;
165 memcpy(&admin->msg.param, param, sizeof(union parameter));
171 * message received from LCR
173 int receive_message(int message_type, unsigned long ref, union parameter *param)
175 union parameter newparam;
176 struct bchannel *bchannel;
177 struct chan_call *call;
179 memset(&newparam, 0, sizeof(union parameter));
181 /* handle bchannel message*/
182 if (message_type == MESSAGE_BCHANNEL)
184 switch(param->bchannel.type)
186 case BCHANNEL_ASSIGN:
187 if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
189 fprintf(stderr, "error: bchannel handle %x already assigned.\n", param->bchannel.handle);
192 /* create bchannel */
193 bchannel = alloc_bchannel(param->bchannel.handle);
196 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", param->bchannel.handle);
200 /* configure channel */
201 bchannel->b_tx_gain = param->bchannel.tx_gain;
202 bchannel->b_rx_gain = param->bchannel.rx_gain;
203 strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
204 if (param->bchannel.crypt_len)
206 bchannel->b_crypt_len = param->bchannel.crypt_len;
207 bchannel->b_crypt_type = param->bchannel.crypt_type;
208 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
210 bchannel->b_txdata = 0;
211 bchannel->b_dtmf = 1;
212 bchannel->b_tx_dejitter = 1;
214 /* in case, ref is not set, this bchannel instance must
215 * be created until it is removed again by LCR */
217 if ((call = find_call_ref(ref)))
220 call->bchannel_handle = param->bchannel.handle;
221 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
222 bchannel_join(call->bridge_id);
224 if (bchannel_create(bchannel))
225 bchannel_activate(bchannel, 1);
228 newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
229 newparam.bchannel.handle = param->bchannel.handle;
230 send_message(MESSAGE_BCHANNEL, 0, &newparam);
233 case BCHANNEL_REMOVE:
234 if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
236 alle fprintf nach ast_log
237 fprintf(stderr, "error: bchannel handle %x not assigned.\n", param->bchannel.handle);
240 /* unlink from call */
241 if ((call = find_call_ref(bchannel->ref)))
243 call->bchannel_handle = 0;
245 /* destroy and remove bchannel */
246 free_bchannel(bchannel);
249 newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
250 newparam.bchannel.handle = param->bchannel.handle;
251 send_message(MESSAGE_BCHANNEL, 0, &newparam);
256 fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
262 if (message_type == MESSAGE_NEWREF)
264 if (param->direction)
266 /* new ref from lcr */
267 if (!ref || find_call_ref(ref))
269 fprintf(stderr, "illegal new ref %d received\n", ref);
276 /* new ref, as requested from this remote application */
277 call = find_call_ref(0);
280 /* send release, if ref does not exist */
281 newparam.disconnectinfo.cause = CAUSE_NORMAL;
282 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
283 send_message(MESSAGE_RELEASE, ref, &newparam);
287 #warning process call (send setup, if pending)
295 fprintf(stderr, "received message %d without ref\n", message_type);
298 call = find_call_ref(ref);
301 /* ignore ref that is not used (anymore) */
305 /* handle messages */
312 case MESSAGE_OVERLAP:
316 case MESSAGE_PROCEEDING:
320 case MESSAGE_ALERTING:
324 case MESSAGE_CONNECT:
328 case MESSAGE_DISCONNECT:
332 case MESSAGE_RELEASE:
337 case MESSAGE_INFORMATION:
341 case MESSAGE_FACILITY:
345 case MESSAGE_PATTERN:
349 case MESSAGE_NOPATTERN:
353 case MESSAGE_AUDIOPATH:
365 * warning! not thread safe
366 * returns -1 for socket error, 0 for no work, 1 for work
368 int handle_socket(void)
372 struct admin_message msg;
373 struct admin_list *admin;
375 /* read from socket */
376 len = read(sock, &msg, sizeof(msg));
379 printf("Socket closed\n");
380 return(-1); // socket closed
384 if (len != sizeof(msg))
386 fprintf(stderr, "Socket short read (%d)\n", len);
387 return(-1); // socket error
389 if (msg.message != ADMIN_MESSAGE)
391 fprintf(stderr, "Socket received illegal message %d\n", msg.message);
392 return(-1); // socket error
394 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
395 printf("message received %d\n", msg.u.msg.type);
399 if (errno != EWOULDBLOCK)
401 fprintf(stderr, "Socket error %d\n", errno);
406 /* write to socket */
410 len = write(sock, &admin->msg, sizeof(msg));
413 printf("Socket closed\n");
414 return(-1); // socket closed
418 if (len != sizeof(msg))
420 fprintf(stderr, "Socket short write (%d)\n", len);
421 return(-1); // socket error
424 admin_first = admin->next;
430 if (errno != EWOULDBLOCK)
432 fprintf(stderr, "Socket error %d\n", errno);
441 * open and close socket
443 int open_socket(void)
447 char *socket_name = SOCKET_NAME;
449 struct sockaddr_un sock_address;
451 unsigned long on = 1;
452 union parameter param;
455 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
457 ast_log(LOG_ERROR, "Failed to create socket.\n");
461 /* set socket address and name */
462 memset(&sock_address, 0, sizeof(sock_address));
463 sock_address.sun_family = PF_UNIX;
464 strcpy(sock_address.sun_path, socket_name);
467 if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
470 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
474 /* set non-blocking io */
475 if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
478 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
482 /* enque hello message */
483 memset(¶m, 0, sizeof(param));
484 strcpy(param.hello.application, "asterisk");
485 send_message(MESSAGE_HELLO, 0, ¶m);
490 void close_socket(int sock)
498 void lcr_thread(void)
507 ret = handle_socket();
514 ret = bchannel_handle();
523 /* call from asterisk (new instance) */
524 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
528 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
529 struct misdn_bchannel *newbc;
530 char *opts=NULL, *ext;
534 strncpy(dest_cp,dest,sizeof(dest_cp)-1);
535 dest_cp[sizeof(dest_cp)]=0;
543 ast_log(LOG_WARNING, "Malformed dialstring\n");
549 ast_log(LOG_WARNING, " --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
553 if (((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) || !dest ) {
554 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
556 ast_setstate(ast, AST_STATE_DOWN);
561 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
563 ast_setstate(ast, AST_STATE_DOWN);
570 ast_log(LOG_WARNING, " --> ! misdn_call called on %s, neither down nor reserved (or dest==NULL)\n", ast->name);
572 ast_setstate(ast, AST_STATE_DOWN);
579 chan_misdn_log(1, port, "* CALL: %s\n",dest);
581 chan_misdn_log(2, port, " --> * dad:%s tech:%s ctx:%s\n",ast->exten,ast->name, ast->context);
583 chan_misdn_log(3, port, " --> * adding2newbc ext %s\n",ast->exten);
585 int l = sizeof(newbc->dad);
586 strncpy(ast->exten,ext,sizeof(ast->exten));
588 strncpy(newbc->dad,ext,l);
593 chan_misdn_log(3, port, " --> * adding2newbc callerid %s\n",AST_CID_P(ast));
594 if (ast_strlen_zero(newbc->oad) && AST_CID_P(ast) ) {
596 if (AST_CID_P(ast)) {
597 int l = sizeof(newbc->oad);
598 strncpy(newbc->oad,AST_CID_P(ast), l);
604 struct chan_list *ch=MISDN_ASTERISK_TECH_PVT(ast);
605 if (!ch) { ast_verbose("No chan_list in misdn_call\n"); return -1;}
607 newbc->capability=ast->transfercapability;
608 pbx_builtin_setvar_helper(ast,"TRANSFERCAPABILITY",ast_transfercapability2str(newbc->capability));
609 if ( ast->transfercapability == INFO_CAPABILITY_DIGITAL_UNRESTRICTED) {
610 chan_misdn_log(2, port, " --> * Call with flag Digital\n");
614 /* update screening and presentation */
615 update_config(ch,ORG_AST);
617 /* fill in some ies from channel vary*/
618 import_ch(ast, newbc, ch);
620 /* Finally The Options Override Everything */
622 misdn_set_opt_exec(ast,opts);
624 chan_misdn_log(2,port,"NO OPTS GIVEN\n");
626 /*check for bridging*/
628 misdn_cfg_get( 0, MISDN_GEN_BRIDGING, &bridging, sizeof(int));
629 if (bridging && ch->other_ch) {
630 chan_misdn_log(1, port, "Disabling EC (aka Pipeline) on both Sides\n");
632 *ch->other_ch->bc->pipeline=0;
635 r=misdn_lib_send_event( newbc, EVENT_SETUP );
637 /** we should have l3id after sending setup **/
638 ch->l3id=newbc->l3_id;
641 if ( r == -ENOCHAN ) {
642 chan_misdn_log(0, port, " --> * Theres no Channel at the moment .. !\n");
643 chan_misdn_log(1, port, " --> * SEND: State Down pid:%d\n",newbc?newbc->pid:-1);
645 ast_setstate(ast, AST_STATE_DOWN);
649 chan_misdn_log(2, port, " --> * SEND: State Dialing pid:%d\n",newbc?newbc->pid:1);
651 ast_setstate(ast, AST_STATE_DIALING);
654 wenn pattern available soll gestoppt werden, sonst nicht:
655 if (newbc->nt) stop_bc_tones(ch);
657 ch->state=MISDN_CALLING;
663 static struct ast_channel_tech misdn_tech = {
665 .description="Channel driver for connecting to Linux-Call-Router",
666 .capabilities= je nach option?AST_FORMAT_ALAW:AST_FORMAT_ULAW ,
667 .requester=lcr_request,
668 .send_digit=lcr_digit,
675 .indicate=lcr_indication,
677 .send_text=lcr_send_text,
683 * module loading and destruction
685 int load_module(void)
687 // ast_mutex_init(&release_lock);
689 // lcr_cfg_update_ptp();
691 if (!(lcr_sock = open_socket())) {
692 ast_log(LOG_ERROR, "Unable to connect %s\n", misdn_type);
694 /* continue with closed socket */
697 if (!bchannel_initialize()) {
698 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
704 if (ast_channel_register(&lcr_tech)) {
705 ast_log(LOG_ERROR, "Unable to register channel class %s\n", misdn_type);
710 ast_cli_register(&cli_show_lcr);
711 ast_cli_register(&cli_show_calls);
713 ast_cli_register(&cli_reload_routing);
714 ast_cli_register(&cli_reload_interfaces);
715 ast_cli_register(&cli_port_block);
716 ast_cli_register(&cli_port_unblock);
718 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
719 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
720 "Sets mISDN opts. and optargs\n"
722 "The available options are:\n"
723 " d - Send display text on called phone, text is the optparam\n"
724 " n - don't detect dtmf tones on called channel\n"
725 " h - make digital outgoing call\n"
726 " c - make crypted outgoing call, param is keyindex\n"
727 " e - perform echo cancelation on this channel,\n"
728 " takes taps as arguments (32,64,128,256)\n"
729 " s - send Non Inband DTMF as inband\n"
730 " vr - rxgain control\n"
731 " vt - txgain control\n"
735 lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
737 chan_lcr_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
742 int unload_module(void)
744 /* First, take us out of the channel loop */
745 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
747 misdn_tasks_destroy();
749 if (!g_config_initialized) return 0;
751 ast_cli_unregister(&cli_show_lcr);
752 ast_cli_unregister(&cli_show_calls);
753 ast_cli_unregister(&cli_reload_routing);
754 ast_cli_unregister(&cli_reload_interfaces);
755 ast_cli_unregister(&cli_port_block);
756 ast_cli_unregister(&cli_port_unblock);
757 ast_unregister_application("misdn_set_opt");
759 ast_channel_unregister(&lcr_tech);
762 bchannel_deinitialize();
771 was ist mit dem mutex
786 ast_mutex_lock(&usecnt_lock);
788 ast_mutex_unlock(&usecnt_lock);
792 char *description(void)
799 return ASTERISK_GPL_KEY;