1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** Asterisk socket client **
10 \*****************************************************************************/
16 To connect, open an LCR socket and send a MESSAGE_HELLO to socket with
17 the application name. This name is unique an can be used for routing calls.
18 Now the channel driver is linked to LCR and can receive and make calls.
21 Call is initiated by LCR:
23 If a call is received from LCR, a MESSAGE_NEWREF is received first.
24 A new chan_call instance is created. The call reference (ref) is given by
25 MESSAGE_NEWREF. The state is CHAN_LCR_STATE_IN_PREPARE.
26 After receiving MESSAGE_SETUP from LCR, the ast_channel instance is created
27 using ast_channel_alloc(1). The setup information is given to asterisk.
28 The new Asterisk instance pointer (ast) is stored to chan_call structure.
29 The state changes to CHAN_LCR_STATE_IN_SETUP.
32 Call is initiated by Asterisk:
34 If a call is reveiced from Asterisk, a new chan_call instance is created.
35 The new Asterisk instance pointer (ast) is stored to chan_call structure.
36 A MESSASGE_NEWREF is sent to LCR requesting a new call reference (ref).
37 The current call ref is set to 0, the state is CHAN_LCR_STATE_OUT_PREPARE.
38 Further dialing information is queued.
39 After the new callref is received by special MESSAGE_NEWREF reply, new ref
40 is stored in the chan_call structure.
41 The setup information is sent to LCR using MESSAGE_SETUP.
42 The state changes to CHAN_LCR_STATE_OUT_SETUP.
47 During call process, messages are received and sent.
48 The state changes accordingly.
49 Any message is allowed to be sent to LCR at any time except MESSAGE_RELEASE.
50 If a MESSAGE_OVERLAP is received, further dialing is required.
51 Queued dialing information, if any, is sent to LCR using MESSAGE_DIALING.
52 In this case, the state changes to CHAN_LCR_STATE_OUT_DIALING.
55 Call is released by LCR:
57 A MESSAGE_RELEASE is received with the call reference (ref) to be released.
58 The current ref is set to 0, to indicate released reference.
59 The state changes to CHAN_LCR_STATE_RELEASE.
60 ast_queue_hangup() is called, if asterisk instance (ast) exists, if not,
61 the chan_call instance is destroyed.
62 After lcr_hangup() is called-back by Asterisk, the chan_call instance
63 is destroyed, because the current ref is set to 0 and the state equals
64 CHAN_LCR_STATE_RELEASE.
65 If the ref is 0 and the state is not CHAN_LCR_STATE_RELEASE, see the proceedure
66 "Call is released by Asterisk".
69 Call is released by Asterisk:
71 lcr_hangup() is called-back by Asterisk. If the call reference (ref) is set,
72 a MESSAGE_RELEASE is sent to LCR and the chan_call instance is destroyed.
73 If the ref is 0 and the state is not CHAN_LCR_STATE_RELEASE, the new state is
74 set to CHAN_LCR_STATE_RELEASE.
75 Later, if the MESSAGE_NEWREF reply is received, a MESSAGE_RELEASE is sent to
76 LCR and the chan_call instance is destroyed.
77 If the ref is 0 and the state is CHAN_LCR_STATE_RELEASE, see the proceedure
78 "Call is released by LCR".
87 #include <sys/types.h>
92 #include <sys/ioctl.h>
93 #include <sys/socket.h>
96 #include <semaphore.h>
98 #include <asterisk/module.h>
99 #include <asterisk/channel.h>
100 #include <asterisk/config.h>
101 #include <asterisk/logger.h>
102 #include <asterisk/pbx.h>
103 #include <asterisk/options.h>
104 #include <asterisk/io.h>
105 #include <asterisk/frame.h>
106 #include <asterisk/translate.h>
107 #include <asterisk/cli.h>
108 #include <asterisk/musiconhold.h>
109 #include <asterisk/dsp.h>
110 #include <asterisk/translate.h>
111 #include <asterisk/file.h>
112 #include <asterisk/callerid.h>
113 #include <asterisk/indications.h>
114 #include <asterisk/app.h>
115 #include <asterisk/features.h>
116 #include <asterisk/sched.h>
118 #include "extension.h"
120 #include "callerid.h"
121 #include "lcrsocket.h"
123 #include "bchannel.h"
124 #include "chan_lcr.h"
126 CHAN_LCR_STATE // state description structure
127 MESSAGES // message text
129 unsigned char flip_bits[256];
134 char lcr_type[]="lcr";
137 ast_mutex_t chan_lock; /* global lock */
138 ast_mutex_t log_lock; /* logging log */
141 int glob_channel = 0;
146 struct admin_list *next;
147 struct admin_message msg;
148 } *admin_first = NULL;
150 static struct ast_channel_tech lcr_tech;
155 void chan_lcr_log(int type, const char *file, int line, const char *function, struct chan_call *call, struct ast_channel *ast, const char *fmt, ...)
158 char call_text[128] = "NULL";
159 char ast_text[128] = "NULL";
162 ast_mutex_lock(&log_lock);
165 vsnprintf(buffer,sizeof(buffer)-1,fmt,args);
166 buffer[sizeof(buffer)-1]=0;
169 if ((unsigned long)call > 1)
170 sprintf(call_text, "%ld", call->ref);
172 strncpy(ast_text, ast->name, sizeof(ast_text)-1);
173 ast_text[sizeof(ast_text)-1] = '\0';
175 ast_log(type, file, line, function, "[call=%s ast=%s] %s", call_text, ast_text, buffer);
177 ast_mutex_unlock(&log_lock);
181 * channel and call instances
183 struct chan_call *call_first;
185 struct chan_call *find_call_ref(unsigned long ref)
187 struct chan_call *call = call_first;
191 if (call->ref == ref)
199 struct chan_call *find_call_ast(struct ast_channel *ast)
201 struct chan_call *call = call_first;
205 if (call->ast == ast)
212 struct chan_call *find_call_handle(unsigned long handle)
214 struct chan_call *call = call_first;
218 if (call->bchannel_handle == handle)
226 void free_call(struct chan_call *call)
228 struct chan_call **temp = &call_first;
234 *temp = (*temp)->next;
235 if (call->pipe[0] > -1)
236 close(call->pipe[0]);
237 if (call->pipe[1] > -1)
238 close(call->pipe[1]);
241 if (call->bchannel->call != call)
242 CERROR(call, NULL, "Linked bchannel structure has no link to us.\n");
243 call->bchannel->call = NULL;
245 if (call->bridge_call)
247 if (call->bridge_call->bridge_call != call)
248 CERROR(call, NULL, "Linked call structure has no link to us.\n");
249 call->bridge_call->bridge_call = NULL;
251 CDEBUG(call, NULL, "Call instance freed.\n");
255 temp = &((*temp)->next);
257 CERROR(call, NULL, "Call instance not found in list.\n");
260 struct chan_call *alloc_call(void)
262 struct chan_call **callp = &call_first;
265 callp = &((*callp)->next);
267 *callp = (struct chan_call *)calloc(1, sizeof(struct chan_call));
269 memset(*callp, 0, sizeof(struct chan_call));
270 if (pipe((*callp)->pipe) < 0) {
271 CERROR(*callp, NULL, "Failed to create pipe.\n");
275 CDEBUG(*callp, NULL, "Call instance allocated.\n");
280 unsigned short new_bridge_id(void)
282 struct chan_call *call;
283 unsigned short id = 1;
285 /* search for lowest bridge id that is not in use and not 0 */
291 if (call->bridge_id == id)
299 CDEBUG(NULL, NULL, "New bridge ID %d.\n", id);
305 * enque message to LCR
307 int send_message(int message_type, unsigned long ref, union parameter *param)
309 struct admin_list *admin, **adminp;
312 CDEBUG(NULL, NULL, "Ignoring message %d, because socket is closed.\n", message_type);
315 CDEBUG(NULL, NULL, "Sending %s to socket.\n", messages_txt[message_type]);
317 adminp = &admin_first;
319 adminp = &((*adminp)->next);
320 admin = (struct admin_list *)calloc(1, sizeof(struct admin_list));
322 CERROR(NULL, NULL, "No memory for message to LCR.\n");
327 admin->msg.message = ADMIN_MESSAGE;
328 admin->msg.u.msg.type = message_type;
329 admin->msg.u.msg.ref = ref;
330 memcpy(&admin->msg.u.msg.param, param, sizeof(union parameter));
336 * send setup info to LCR
337 * this function is called, when asterisk call is received and ref is received
339 static void send_setup_to_lcr(struct chan_call *call)
341 union parameter newparam;
342 struct ast_channel *ast = call->ast;
344 if (!call->ast || !call->ref)
347 CDEBUG(call, call->ast, "Sending setup to LCR.\n");
349 /* send setup message to LCR */
350 memset(&newparam, 0, sizeof(union parameter));
351 strncpy(newparam.setup.dialinginfo.id, ast->exten, sizeof(newparam.setup.dialinginfo.id)-1);
352 newparam.setup.callerinfo.itype = INFO_ITYPE_CHAN;
353 newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
354 if (ast->cid.cid_num) if (ast->cid.cid_num[0])
355 strncpy(newparam.setup.callerinfo.id, ast->cid.cid_num, sizeof(newparam.setup.callerinfo.id)-1);
356 if (ast->cid.cid_name) if (ast->cid.cid_name[0])
357 strncpy(newparam.setup.callerinfo.name, ast->cid.cid_name, sizeof(newparam.setup.callerinfo.name)-1);
358 if (ast->cid.cid_rdnis) if (ast->cid.cid_rdnis[0])
360 strncpy(newparam.setup.redirinfo.id, ast->cid.cid_rdnis, sizeof(newparam.setup.redirinfo.id)-1);
361 newparam.setup.redirinfo.itype = INFO_ITYPE_CHAN;
362 newparam.setup.redirinfo.ntype = INFO_NTYPE_UNKNOWN;
364 switch(ast->cid.cid_pres & AST_PRES_RESTRICTION)
366 case AST_PRES_ALLOWED:
367 newparam.setup.callerinfo.present = INFO_PRESENT_ALLOWED;
369 case AST_PRES_RESTRICTED:
370 newparam.setup.callerinfo.present = INFO_PRESENT_RESTRICTED;
372 case AST_PRES_UNAVAILABLE:
373 newparam.setup.callerinfo.present = INFO_PRESENT_NOTAVAIL;
376 newparam.setup.callerinfo.present = INFO_PRESENT_NULL;
378 switch(ast->cid.cid_ton)
381 newparam.setup.callerinfo.ntype = INFO_NTYPE_SUBSCRIBER;
384 newparam.setup.callerinfo.ntype = INFO_NTYPE_NATIONAL;
387 newparam.setup.callerinfo.ntype = INFO_NTYPE_INTERNATIONAL;
390 newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
392 newparam.setup.capainfo.bearer_capa = ast->transfercapability;
394 newparam.setup.capainfo.bearer_info1 = alaw 3, ulaw 2;
396 newparam.setup.capainfo.bearer_info1 = 3;
397 newparam.setup.capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
398 newparam.setup.capainfo.hlc = INFO_HLC_NONE;
399 newparam.setup.capainfo.exthlc = INFO_HLC_NONE;
400 send_message(MESSAGE_SETUP, call->ref, &newparam);
402 /* change to outgoing setup state */
403 call->state = CHAN_LCR_STATE_OUT_SETUP;
407 * send dialing info to LCR
408 * this function is called, when setup acknowledge is received and dialing
411 static void send_dialque_to_lcr(struct chan_call *call)
413 union parameter newparam;
415 if (!call->ast || !call->ref || !call->dialque[0])
418 CDEBUG(call, call->ast, "Sending dial queue to LCR. (dialing=%s)\n", call->dialque);
420 /* send setup message to LCR */
421 memset(&newparam, 0, sizeof(union parameter));
422 strncpy(newparam.information.id, call->dialque, sizeof(newparam.information.id)-1);
423 call->dialque[0] = '\0';
424 send_message(MESSAGE_INFORMATION, call->ref, &newparam);
428 * in case of a bridge, the unsupported message can be forwarded directly
429 * to the remote call.
431 static void bridge_message_if_bridged(struct chan_call *call, int message_type, union parameter *param)
435 if (!call->bridge_call) return;
436 CDEBUG(call, NULL, "Sending message due briding.\n");
437 send_message(message_type, call->bridge_call->ref, param);
441 * send release message to LCR and import bchannel if exported
443 static void send_release_and_import(struct chan_call *call, int cause, int location)
445 union parameter newparam;
447 /* importing channel */
448 if (call->bchannel && call->bchannel->handle) {
449 memset(&newparam, 0, sizeof(union parameter));
450 newparam.bchannel.type = BCHANNEL_RELEASE;
451 newparam.bchannel.handle = call->bchannel->handle;
452 send_message(MESSAGE_BCHANNEL, call->ref, &newparam);
454 /* sending release */
455 memset(&newparam, 0, sizeof(union parameter));
456 newparam.disconnectinfo.cause = cause;
457 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
458 send_message(MESSAGE_RELEASE, call->ref, &newparam);
462 * check if extension matches and start asterisk
463 * if it can match, proceed
466 static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int complete)
469 union parameter newparam;
471 CDEBUG(call, ast, "Try to start pbx. (exten=%s context=%s complete=%s)\n", ast->exten, ast->context, complete?"yes":"no");
476 if (!ast_canmatch_extension(ast, ast->context, ast->exten, 1, call->oad))
478 CDEBUG(call, ast, "Got 'sending complete', but extension '%s' will not match at context '%s' - releasing.\n", ast->exten, ast->context);
482 if (!ast_exists_extension(ast, ast->context, ast->exten, 1, call->oad))
484 CDEBUG(call, ast, "Got 'sending complete', but extension '%s' would match at context '%s', if more digits would be dialed - releasing.\n", ast->exten, ast->context);
488 CDEBUG(call, ast, "Got 'sending complete', extensions matches.\n");
489 /* send setup acknowledge to lcr */
490 memset(&newparam, 0, sizeof(union parameter));
491 send_message(MESSAGE_PROCEEDING, call->ref, &newparam);
494 call->state = CHAN_LCR_STATE_IN_PROCEEDING;
499 if (ast_canmatch_extension(ast, ast->context, ast->exten, 1, call->oad))
501 /* send setup acknowledge to lcr */
502 if (call->state != CHAN_LCR_STATE_IN_DIALING) {
503 memset(&newparam, 0, sizeof(union parameter));
504 send_message(MESSAGE_OVERLAP, call->ref, &newparam);
508 call->state = CHAN_LCR_STATE_IN_DIALING;
510 /* if match, start pbx */
511 if (ast_exists_extension(ast, ast->context, ast->exten, 1, call->oad)) {
512 CDEBUG(call, ast, "Extensions matches.\n");
517 CDEBUG(call, ast, "Extensions may match, if more digits are dialed.\n");
525 CDEBUG(call, ast, "Releasing due to extension missmatch.\n");
526 send_release_and_import(call, cause, LOCATION_PRIVATE_LOCAL);
528 /* release asterisk */
529 ast->hangupcause = call->cause;
530 /* change to release state */
531 call->state = CHAN_LCR_STATE_RELEASE;
532 ast_hangup(ast); // call will be destroyed here
536 /* send setup to asterisk */
537 CDEBUG(call, ast, "Starting call to Asterisk due to matching extension.\n");
538 ret = ast_pbx_start(ast);
541 cause = (ret==-2)?34:27;
544 call->pbx_started = 1;
549 * incoming setup from LCR
551 static void lcr_in_setup(struct chan_call *call, int message_type, union parameter *param)
553 struct ast_channel *ast;
555 CDEBUG(call, NULL, "Incomming setup from LCR. (callerid %s, dialing %s)\n", param->setup.callerinfo.id, param->setup.dialinginfo.id);
557 /* create asterisk channel instrance */
558 ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
562 CERROR(call, NULL, "Failed to create Asterisk channel - releasing.\n");
563 send_release_and_import(call, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL);
570 ast->tech_pvt = call;
571 ast->tech = &lcr_tech;
572 ast->fds[0] = call->pipe[0];
574 /* fill setup information */
575 if (param->setup.dialinginfo.id)
576 strncpy(ast->exten, param->setup.dialinginfo.id, AST_MAX_EXTENSION-1);
577 if (param->setup.context[0])
578 strncpy(ast->context, param->setup.context, AST_MAX_CONTEXT-1);
580 strncpy(ast->context, param->setup.callerinfo.interface, AST_MAX_CONTEXT-1);
581 if (param->setup.callerinfo.id[0])
582 ast->cid.cid_num = strdup(param->setup.callerinfo.id);
583 if (param->setup.callerinfo.name[0])
584 ast->cid.cid_name = strdup(param->setup.callerinfo.name);
586 if (param->setup.redirinfo.id[0])
587 ast->cid.cid_name = strdup(numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, configfile->prefix_nat, configfile->prefix_inter));
589 switch (param->setup.callerinfo.present)
591 case INFO_PRESENT_ALLOWED:
592 ast->cid.cid_pres = AST_PRES_ALLOWED;
594 case INFO_PRESENT_RESTRICTED:
595 ast->cid.cid_pres = AST_PRES_RESTRICTED;
598 ast->cid.cid_pres = AST_PRES_UNAVAILABLE;
600 switch (param->setup.callerinfo.ntype)
602 case INFO_NTYPE_SUBSCRIBER:
603 ast->cid.cid_ton = 4;
605 case INFO_NTYPE_NATIONAL:
606 ast->cid.cid_ton = 2;
608 case INFO_NTYPE_INTERNATIONAL:
609 ast->cid.cid_ton = 1;
612 ast->cid.cid_ton = 0;
614 ast->transfercapability = param->setup.capainfo.bearer_capa;
616 strncpy(call->oad, numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, configfile->prefix_nat, configfile->prefix_inter), sizeof(call->oad)-1);
618 strncpy(call->oad, numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, "0", "00"), sizeof(call->oad)-1);
621 /* configure channel */
623 ast->nativeformats = configfile->lawformat;
624 ast->readformat = ast->rawreadformat = configfile->lawformat;
625 ast->writeformat = ast->rawwriteformat = configfile->lawformat;
627 ast->nativeformats = AST_FORMAT_ALAW;
628 ast->readformat = ast->rawreadformat = AST_FORMAT_ALAW;
629 ast->writeformat = ast->rawwriteformat = AST_FORMAT_ALAW;
632 ast->hangupcause = 0;
635 call->state = CHAN_LCR_STATE_IN_SETUP;
637 lcr_start_pbx(call, ast, param->setup.dialinginfo.sending_complete);
641 * incoming setup acknowledge from LCR
643 static void lcr_in_overlap(struct chan_call *call, int message_type, union parameter *param)
645 if (!call->ast) return;
647 CDEBUG(call, call->ast, "Incomming setup acknowledge from LCR.\n");
649 /* send pending digits in dialque */
650 if (call->dialque[0])
651 send_dialque_to_lcr(call);
652 /* change to overlap state */
653 call->state = CHAN_LCR_STATE_OUT_DIALING;
657 * incoming proceeding from LCR
659 static void lcr_in_proceeding(struct chan_call *call, int message_type, union parameter *param)
661 CDEBUG(call, call->ast, "Incomming proceeding from LCR.\n");
664 call->state = CHAN_LCR_STATE_OUT_PROCEEDING;
665 /* send event to asterisk */
666 if (call->ast && call->pbx_started)
667 ast_queue_control(call->ast, AST_CONTROL_PROCEEDING);
671 * incoming alerting from LCR
673 static void lcr_in_alerting(struct chan_call *call, int message_type, union parameter *param)
675 CDEBUG(call, call->ast, "Incomming alerting from LCR.\n");
678 call->state = CHAN_LCR_STATE_OUT_ALERTING;
679 /* send event to asterisk */
680 if (call->ast && call->pbx_started)
681 ast_queue_control(call->ast, AST_CONTROL_RINGING);
685 * incoming connect from LCR
687 static void lcr_in_connect(struct chan_call *call, int message_type, union parameter *param)
689 union parameter newparam;
691 CDEBUG(call, call->ast, "Incomming connect (answer) from LCR.\n");
694 call->state = CHAN_LCR_STATE_CONNECT;
695 /* request bchannel */
696 if (!call->bchannel) {
697 CDEBUG(call, call->ast, "Requesting B-channel.\n");
698 memset(&newparam, 0, sizeof(union parameter));
699 newparam.bchannel.type = BCHANNEL_REQUEST;
700 send_message(MESSAGE_BCHANNEL, call->ref, &newparam);
702 /* copy connectinfo */
703 memcpy(&call->connectinfo, ¶m->connectinfo, sizeof(struct connect_info));
704 /* send event to asterisk */
705 if (call->ast && call->pbx_started)
706 ast_queue_control(call->ast, AST_CONTROL_ANSWER);
710 * incoming disconnect from LCR
712 static void lcr_in_disconnect(struct chan_call *call, int message_type, union parameter *param)
714 struct ast_channel *ast = call->ast;
716 CDEBUG(call, call->ast, "Incomming disconnect from LCR. (cause=%d)\n", param->disconnectinfo.cause);
719 call->state = CHAN_LCR_STATE_IN_DISCONNECT;
721 call->cause = param->disconnectinfo.cause;
722 call->location = param->disconnectinfo.location;
723 /* if bridge, forward disconnect and return */
726 if (call->bridge_call)
728 CDEBUG(call, call->ast, "Only signal disconnect via bridge.\n");
729 bridge_message_if_bridged(call, message_type, param);
733 /* release lcr with same cause */
734 send_release_and_import(call, call->cause, call->location);
736 /* change to release state */
737 call->state = CHAN_LCR_STATE_RELEASE;
738 /* release asterisk */
741 ast->hangupcause = call->cause;
742 if (call->pbx_started)
743 ast_queue_hangup(ast);
745 ast_hangup(ast); // call will be destroyed here
751 * incoming setup acknowledge from LCR
753 static void lcr_in_release(struct chan_call *call, int message_type, union parameter *param)
755 struct ast_channel *ast = call->ast;
757 CDEBUG(call, call->ast, "Incomming release from LCR, releasing ref. (cause=%d)\n", param->disconnectinfo.cause);
761 /* change to release state */
762 call->state = CHAN_LCR_STATE_RELEASE;
763 /* copy release info */
766 call->cause = param->disconnectinfo.cause;
767 call->location = param->disconnectinfo.location;
769 /* if we have an asterisk instance, send hangup, else we are done */
772 ast->hangupcause = call->cause;
773 if (call->pbx_started)
774 ast_queue_hangup(ast);
776 ast_hangup(ast); // call will be destroyed here
786 * incoming information from LCR
788 static void lcr_in_information(struct chan_call *call, int message_type, union parameter *param)
790 struct ast_channel *ast = call->ast;
794 CDEBUG(call, call->ast, "Incoming information from LCR. (dialing=%s)\n", param->information.id);
798 /* pbx not started */
799 if (!call->pbx_started)
801 CDEBUG(call, call->ast, "Asterisk not started, adding digits to number.\n");
802 strncat(ast->exten, param->information.id, AST_MAX_EXTENSION-1);
803 lcr_start_pbx(call, ast, param->information.sending_complete);
808 p = param->information.id;
809 if (call->state == CHAN_LCR_STATE_IN_DIALING && *p)
811 CDEBUG(call, call->ast, "Asterisk is started, sending DTMF frame.\n");
814 /* send digit to asterisk */
815 memset(&fr, 0, sizeof(fr));
816 fr.frametype = AST_FRAME_DTMF;
818 fr.delivery = ast_tv(0, 0);
819 ast_queue_frame(call->ast, &fr);
823 /* use bridge to forware message not supported by asterisk */
824 if (call->state == CHAN_LCR_STATE_CONNECT) {
825 CDEBUG(call, call->ast, "Call is connected, briding.\n");
826 bridge_message_if_bridged(call, message_type, param);
831 * incoming information from LCR
833 static void lcr_in_notify(struct chan_call *call, int message_type, union parameter *param)
835 CDEBUG(call, call->ast, "Incomming notify from LCR. (notify=%d)\n", param->notifyinfo.notify);
837 if (!call->ast) return;
839 /* use bridge to forware message not supported by asterisk */
840 bridge_message_if_bridged(call, message_type, param);
844 * incoming information from LCR
846 static void lcr_in_facility(struct chan_call *call, int message_type, union parameter *param)
848 CDEBUG(call, call->ast, "Incomming facility from LCR.\n");
850 if (!call->ast) return;
852 /* use bridge to forware message not supported by asterisk */
853 bridge_message_if_bridged(call, message_type, param);
857 * message received from LCR
859 int receive_message(int message_type, unsigned long ref, union parameter *param)
861 union parameter newparam;
862 struct bchannel *bchannel;
863 struct chan_call *call;
865 memset(&newparam, 0, sizeof(union parameter));
867 /* handle bchannel message*/
868 if (message_type == MESSAGE_BCHANNEL)
870 switch(param->bchannel.type)
872 case BCHANNEL_ASSIGN:
873 CDEBUG(NULL, NULL, "Received BCHANNEL_ASSIGN message. (handle=%08lx)\n", param->bchannel.handle);
874 if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
876 CERROR(NULL, NULL, "bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
879 /* create bchannel */
880 bchannel = alloc_bchannel(param->bchannel.handle);
883 CERROR(NULL, NULL, "alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
887 /* configure channel */
888 bchannel->b_tx_gain = param->bchannel.tx_gain;
889 bchannel->b_rx_gain = param->bchannel.rx_gain;
890 strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
891 if (param->bchannel.crypt_len)
893 bchannel->b_crypt_len = param->bchannel.crypt_len;
894 bchannel->b_crypt_type = param->bchannel.crypt_type;
895 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
897 bchannel->b_txdata = 0;
898 bchannel->b_dtmf = 1;
899 bchannel->b_tx_dejitter = 1;
901 /* in case, ref is not set, this bchannel instance must
902 * be created until it is removed again by LCR */
904 if ((call = find_call_ref(ref)))
906 bchannel->call = call;
907 call->bchannel = bchannel;
909 hier muesen alle bchannel-features gesetzt werden (pipeline...) falls sie vor dem b-kanal verfügbar waren
911 if (call->bridge_id) {
912 CDEBUG(call, call->ast, "Join bchannel, because call is already bridged.\n");
913 bchannel_join(bchannel, call->bridge_id);
916 if (bchannel_create(bchannel))
917 bchannel_activate(bchannel, 1);
920 newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
921 newparam.bchannel.handle = param->bchannel.handle;
922 send_message(MESSAGE_BCHANNEL, 0, &newparam);
925 case BCHANNEL_REMOVE:
926 CDEBUG(NULL, NULL, "Received BCHANNEL_REMOVE message. (handle=%08lx)\n", param->bchannel.handle);
927 if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
929 CERROR(NULL, NULL, "Bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
932 /* unklink from call and destroy bchannel */
933 free_bchannel(bchannel);
936 newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
937 newparam.bchannel.handle = param->bchannel.handle;
938 send_message(MESSAGE_BCHANNEL, 0, &newparam);
943 CDEBUG(NULL, NULL, "Received unknown bchannel message %d.\n", param->bchannel.type);
949 if (message_type == MESSAGE_NEWREF)
951 if (param->direction)
953 /* new ref from lcr */
954 CDEBUG(NULL, NULL, "Received new ref by LCR, due to incomming call. (ref=%ld)\n", ref);
955 if (!ref || find_call_ref(ref))
957 CERROR(NULL, NULL, "Illegal new ref %ld received.\n", ref);
960 /* allocate new call instance */
963 call->state = CHAN_LCR_STATE_IN_PREPARE;
966 /* wait for setup (or release from asterisk) */
969 /* new ref, as requested from this remote application */
970 CDEBUG(NULL, NULL, "Received new ref by LCR, as requested from chan_lcr. (ref=%ld)\n", ref);
971 call = find_call_ref(0);
974 /* send release, if ref does not exist */
975 CDEBUG(NULL, NULL, "No call found, that requests a ref.\n");
976 send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL);
981 /* send pending setup info */
982 if (call->state == CHAN_LCR_STATE_OUT_PREPARE)
983 send_setup_to_lcr(call);
984 /* release if asterisk has signed off */
985 else if (call->state == CHAN_LCR_STATE_RELEASE)
989 send_release_and_import(call, call->cause, call->location);
991 send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL);
1003 CERROR(NULL, NULL, "Received message %d without ref.\n", message_type);
1006 call = find_call_ref(ref);
1009 /* ignore ref that is not used (anymore) */
1010 CDEBUG(NULL, NULL, "Message %d from LCR ignored, because no call instance found.\n", message_type);
1014 /* handle messages */
1015 switch(message_type)
1018 lcr_in_setup(call, message_type, param);
1021 case MESSAGE_OVERLAP:
1022 lcr_in_overlap(call, message_type, param);
1025 case MESSAGE_PROCEEDING:
1026 lcr_in_proceeding(call, message_type, param);
1029 case MESSAGE_ALERTING:
1030 lcr_in_alerting(call, message_type, param);
1033 case MESSAGE_CONNECT:
1034 lcr_in_connect(call, message_type, param);
1037 case MESSAGE_DISCONNECT:
1038 lcr_in_disconnect(call, message_type, param);
1041 case MESSAGE_RELEASE:
1042 lcr_in_release(call, message_type, param);
1045 case MESSAGE_INFORMATION:
1046 lcr_in_information(call, message_type, param);
1049 case MESSAGE_NOTIFY:
1050 lcr_in_notify(call, message_type, param);
1053 case MESSAGE_FACILITY:
1054 lcr_in_facility(call, message_type, param);
1057 case MESSAGE_PATTERN: // audio available from LCR
1060 case MESSAGE_NOPATTERN: // audio not available from LCR
1063 case MESSAGE_AUDIOPATH: // if remote audio connected or hold
1064 call->audiopath = param->audiopath;
1068 CDEBUG(call, call->ast, "Message %d from LCR unhandled.\n", message_type);
1075 * release all calls (due to broken socket)
1077 static void release_all_calls(void)
1079 struct chan_call *call;
1084 /* no ast, so we may directly free call */
1086 CDEBUG(call, NULL, "Freeing call, because no Asterisk channel is linked.\n");
1090 /* already in release process */
1091 if (call->state == CHAN_LCR_STATE_RELEASE) {
1095 /* release or queue release */
1097 call->state = CHAN_LCR_STATE_RELEASE;
1098 if (!call->pbx_started) {
1099 CDEBUG(call, call->ast, "Releasing call, because no Asterisk channel is not started.\n");
1100 ast_hangup(call->ast); // call will be destroyed here
1103 CDEBUG(call, call->ast, "Queue call release, because Asterisk channel is running.\n");
1104 ast_queue_hangup(call->ast);
1108 /* release all bchannels */
1109 while(bchannel_first)
1110 free_bchannel(bchannel_first);
1115 * warning! not thread safe
1116 * returns -1 for socket error, 0 for no work, 1 for work
1118 int handle_socket(void)
1122 struct admin_list *admin;
1123 struct admin_message msg;
1125 /* read from socket */
1126 len = read(lcr_sock, &msg, sizeof(msg));
1129 CERROR(NULL, NULL, "Socket closed.\n");
1130 return(-1); // socket closed
1134 if (len != sizeof(msg))
1136 CERROR(NULL, NULL, "Socket short read. (len %d)\n", len);
1137 return(-1); // socket error
1139 if (msg.message != ADMIN_MESSAGE)
1141 CERROR(NULL, NULL, "Socket received illegal message %d.\n", msg.message);
1144 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
1148 if (errno != EWOULDBLOCK)
1150 CERROR(NULL, NULL, "Socket failed (errno %d).\n", errno);
1155 /* write to socket */
1158 admin = admin_first;
1159 len = write(lcr_sock, &admin->msg, sizeof(msg));
1162 CERROR(NULL, NULL, "Socket closed.\n");
1163 return(-1); // socket closed
1167 if (len != sizeof(msg))
1169 CERROR(NULL, NULL, "Socket short write. (len %d)\n", len);
1170 return(-1); // socket error
1173 admin_first = admin->next;
1179 if (errno != EWOULDBLOCK)
1181 CERROR(NULL, NULL, "Socket failed (errno %d).\n", errno);
1190 * open and close socket and thread
1192 int open_socket(void)
1195 char *socket_name = SOCKET_NAME;
1197 struct sockaddr_un sock_address;
1198 unsigned long on = 1;
1199 union parameter param;
1202 if ((lcr_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1204 CERROR(NULL, NULL, "Failed to create socket.\n");
1208 /* set socket address and name */
1209 memset(&sock_address, 0, sizeof(sock_address));
1210 sock_address.sun_family = PF_UNIX;
1211 strcpy(sock_address.sun_path, socket_name);
1213 /* connect socket */
1214 if ((conn = connect(lcr_sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
1218 CDEBUG(NULL, NULL, "Failed to connect to socket '%s'. Is LCR running?\n", sock_address.sun_path);
1222 /* set non-blocking io */
1223 if ((ret = ioctl(lcr_sock, FIONBIO, (unsigned char *)(&on))) < 0)
1227 CERROR(NULL, NULL, "Failed to set socket into non-blocking IO.\n");
1231 /* enque hello message */
1232 memset(¶m, 0, sizeof(param));
1233 strcpy(param.hello.application, "asterisk");
1234 send_message(MESSAGE_HELLO, 0, ¶m);
1239 void close_socket(void)
1241 struct admin_list *admin, *temp;
1243 /* flush pending messages */
1244 admin = admin_first;
1247 admin = admin->next;
1258 void sighandler(int sigset)
1262 static void *chan_thread(void *arg)
1266 union parameter param;
1267 time_t retry = 0, now;
1269 bchannel_pid = getpid();
1271 // signal(SIGPIPE, sighandler);
1273 memset(¶m, 0, sizeof(union parameter));
1277 ast_mutex_lock(&chan_lock);
1284 ret = handle_socket();
1286 CERROR(NULL, NULL, "Handling of socket failed - closing for some seconds.\n");
1288 release_all_calls();
1295 if (retry && now-retry > 5) {
1296 CDEBUG(NULL, NULL, "Retry to open socket.\n");
1298 if (open_socket() < 0) {
1307 ret = bchannel_handle();
1312 ast_mutex_unlock(&chan_lock);
1314 ast_mutex_lock(&chan_lock);
1320 CERROR(NULL, NULL, "Thread exit.\n");
1322 ast_mutex_unlock(&chan_lock);
1324 // signal(SIGPIPE, SIG_DFL);
1330 * new asterisk instance
1333 struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
1335 struct ast_channel *ast;
1337 ast_mutex_lock(&chan_lock);
1339 CDEBUG(NULL, NULL, "Received request from Asterisk.\n");
1341 /* if socket is closed */
1344 CERROR(NULL, NULL, "Rejecting call from Asterisk, because LCR not running.\n");
1348 /* create asterisk channel instrance */
1349 ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
1352 CERROR(NULL, NULL, "Failed to create Asterisk channel.\n");
1353 /* failed to create instance */
1356 ast->tech = &lcr_tech;
1357 ast->tech_pvt = (void *)1L; // or asterisk will not call
1358 /* configure channel */
1360 snprintf(ast->name, sizeof(ast->name), "%s/%d", lcr_type, ++glob_channel);
1361 ast->name[sizeof(ast->name)-1] = '\0';
1364 ast->nativeformats = configfile->lawformat;
1365 ast->readformat = ast->rawreadformat = configfile->lawformat;
1366 ast->writeformat = ast->rawwriteformat = configfile->lawformat;
1368 ast->nativeformats = AST_FORMAT_ALAW;
1369 ast->readformat = ast->rawreadformat = AST_FORMAT_ALAW;
1370 ast->writeformat = ast->rawwriteformat = AST_FORMAT_ALAW;
1373 ast->hangupcause = 0;
1375 ast_mutex_unlock(&chan_lock);
1381 * call from asterisk
1383 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
1385 struct chan_call *call;
1386 union parameter newparam;
1388 ast_mutex_lock(&chan_lock);
1389 call = ast->tech_pvt;
1390 if ((unsigned long)call > 1) {
1391 CERROR(NULL, ast, "Received call from Asterisk, but call instance already exists.\n");
1392 ast_mutex_unlock(&chan_lock);
1396 CDEBUG(NULL, ast, "Received call from Asterisk.\n");
1398 /* create call instance */
1399 call = alloc_call();
1402 /* failed to create instance */
1407 ast->tech_pvt = call;
1408 ast->fds[0] = call->pipe[0];
1409 /* pbx process is started */
1410 call->pbx_started = 1;
1411 /* send MESSAGE_NEWREF */
1412 memset(&newparam, 0, sizeof(union parameter));
1413 newparam.direction = 0; /* request from app */
1414 send_message(MESSAGE_NEWREF, 0, &newparam);
1416 call->state = CHAN_LCR_STATE_OUT_PREPARE;
1418 ast_mutex_unlock(&chan_lock);
1422 static int lcr_digit(struct ast_channel *ast, char digit)
1424 struct chan_call *call;
1425 union parameter newparam;
1428 /* only pass IA5 number space */
1429 if (digit > 126 || digit < 32)
1432 ast_mutex_lock(&chan_lock);
1433 call = ast->tech_pvt;
1434 if ((unsigned long)call <= 1) {
1435 CERROR(NULL, ast, "Received digit from Asterisk, but no call instance exists.\n");
1436 ast_mutex_unlock(&chan_lock);
1440 CDEBUG(call, ast, "Received digit Asterisk.\n");
1442 /* send information or queue them */
1443 if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING)
1445 CDEBUG(call, ast, "Sending digit to LCR, because we are in dialing state.\n");
1446 memset(&newparam, 0, sizeof(union parameter));
1447 newparam.information.id[0] = digit;
1448 newparam.information.id[1] = '\0';
1449 send_message(MESSAGE_INFORMATION, call->ref, &newparam);
1452 && (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP));
1454 CDEBUG(call, ast, "Queue digits, because we are in setup/dialing state and have no ref yet.\n");
1456 strncat(call->dialque, buf, strlen(call->dialque)-1);
1459 ast_mutex_unlock(&chan_lock);
1464 static int lcr_answer(struct ast_channel *ast)
1466 union parameter newparam;
1467 struct chan_call *call;
1469 ast_mutex_lock(&chan_lock);
1470 call = ast->tech_pvt;
1471 if ((unsigned long)call <= 1) {
1472 CERROR(NULL, ast, "Received answer from Asterisk, but no call instance exists.\n");
1473 ast_mutex_unlock(&chan_lock);
1477 CDEBUG(call, ast, "Received answer from Asterisk.\n");
1479 /* copy connectinfo, if bridged */
1480 if (call->bridge_call)
1481 memcpy(&call->connectinfo, &call->bridge_call->connectinfo, sizeof(struct connect_info));
1482 /* send connect message to lcr */
1483 memset(&newparam, 0, sizeof(union parameter));
1484 memcpy(&newparam.connectinfo, &call->connectinfo, sizeof(struct connect_info));
1485 send_message(MESSAGE_CONNECT, call->ref, &newparam);
1487 call->state = CHAN_LCR_STATE_CONNECT;
1488 /* request bchannel */
1489 if (!call->bchannel) {
1490 CDEBUG(call, ast, "Requesting B-channel.\n");
1491 memset(&newparam, 0, sizeof(union parameter));
1492 newparam.bchannel.type = BCHANNEL_REQUEST;
1493 send_message(MESSAGE_BCHANNEL, call->ref, &newparam);
1496 ast_mutex_unlock(&chan_lock);
1500 static int lcr_hangup(struct ast_channel *ast)
1502 struct chan_call *call;
1503 pthread_t tid = pthread_self();
1505 if (!pthread_equal(tid, chan_tid))
1506 ast_mutex_lock(&chan_lock);
1507 call = ast->tech_pvt;
1508 if ((unsigned long)call <= 1) {
1509 CERROR(NULL, ast, "Received hangup from Asterisk, but no call instance exists.\n");
1510 if (!pthread_equal(tid, chan_tid))
1511 ast_mutex_unlock(&chan_lock);
1515 if (!pthread_equal(tid, chan_tid))
1516 CDEBUG(call, ast, "Received hangup from Asterisk thread.\n");
1518 CDEBUG(call, ast, "Received hangup from LCR thread.\n");
1520 /* disconnect asterisk, maybe not required */
1521 ast->tech_pvt = NULL;
1526 CDEBUG(call, ast, "Releasing ref and freeing call instance.\n");
1527 if (ast->hangupcause > 0)
1528 send_release_and_import(call, ast->hangupcause, LOCATION_PRIVATE_LOCAL);
1530 send_release_and_import(call, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL);
1533 if (!pthread_equal(tid, chan_tid))
1534 ast_mutex_unlock(&chan_lock);
1538 /* ref is not set, due to prepare setup or release */
1539 if (call->state == CHAN_LCR_STATE_RELEASE)
1541 /* we get the response to our release */
1542 CDEBUG(call, ast, "Freeing call instance, because we have no ref AND we are requesting no ref.\n");
1546 /* during prepare, we change to release state */
1547 CDEBUG(call, ast, "We must wait until we received our ref, until we can free call instance.\n");
1548 call->state = CHAN_LCR_STATE_RELEASE;
1551 if (!pthread_equal(tid, chan_tid))
1552 ast_mutex_unlock(&chan_lock);
1556 static int lcr_write(struct ast_channel *ast, struct ast_frame *f)
1558 struct chan_call *call;
1561 CDEBUG(NULL, ast, "No subclass\n");
1565 if (!(f->subclass & AST_FORMAT_ALAW))
1567 CDEBUG(NULL, ast, "Unexpected format.\n");
1569 ast_mutex_lock(&chan_lock);
1570 call = ast->tech_pvt;
1571 if ((unsigned long)call <= 1) {
1572 ast_mutex_unlock(&chan_lock);
1575 if (call->bchannel && f->samples)
1576 bchannel_transmit(call->bchannel, f->data, f->samples);
1577 ast_mutex_unlock(&chan_lock);
1582 static struct ast_frame *lcr_read(struct ast_channel *ast)
1584 struct chan_call *call;
1588 ast_mutex_lock(&chan_lock);
1589 call = ast->tech_pvt;
1590 if ((unsigned long)call <= 1) {
1591 ast_mutex_unlock(&chan_lock);
1594 if (call->pipe[0] > -1) {
1595 len = read(call->pipe[0], call->read_buff, sizeof(call->read_buff));
1597 close(call->pipe[0]);
1603 p = call->read_buff;
1604 for (i = 0; i < len; i++) {
1609 call->read_fr.frametype = AST_FRAME_VOICE;
1613 call->read_fr.subclass = AST_FORMAT_ALAW;
1615 call->read_fr.datalen = len;
1616 call->read_fr.samples = len;
1617 call->read_fr.delivery = ast_tv(0,0);
1618 call->read_fr.data = call->read_buff;
1619 ast_mutex_unlock(&chan_lock);
1621 return &call->read_fr;
1624 static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, size_t datalen)
1626 union parameter newparam;
1628 struct chan_call *call;
1630 ast_mutex_lock(&chan_lock);
1631 call = ast->tech_pvt;
1632 if ((unsigned long)call <= 1) {
1633 CERROR(NULL, ast, "Received indicate from Asterisk, but no call instance exists.\n");
1634 ast_mutex_unlock(&chan_lock);
1639 case AST_CONTROL_BUSY:
1640 CDEBUG(call, ast, "Received indicate AST_CONTROL_BUSY from Asterisk.\n");
1641 ast_setstate(ast, AST_STATE_BUSY);
1642 if (call->state != CHAN_LCR_STATE_OUT_DISCONNECT) {
1643 /* send message to lcr */
1644 memset(&newparam, 0, sizeof(union parameter));
1645 newparam.disconnectinfo.cause = 17;
1646 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1647 send_message(MESSAGE_DISCONNECT, call->ref, &newparam);
1649 call->state = CHAN_LCR_STATE_OUT_DISCONNECT;
1652 case AST_CONTROL_CONGESTION:
1653 CDEBUG(call, ast, "Received indicate AST_CONTROL_CONGESTION from Asterisk. (cause %d)\n", ast->hangupcause);
1654 if (call->state != CHAN_LCR_STATE_OUT_DISCONNECT) {
1655 /* send message to lcr */
1656 memset(&newparam, 0, sizeof(union parameter));
1657 newparam.disconnectinfo.cause = ast->hangupcause;
1658 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1659 send_message(MESSAGE_DISCONNECT, call->ref, &newparam);
1661 call->state = CHAN_LCR_STATE_OUT_DISCONNECT;
1664 case AST_CONTROL_PROCEEDING:
1665 CDEBUG(call, ast, "Received indicate AST_CONTROL_PROCEEDING from Asterisk.\n");
1666 if (call->state == CHAN_LCR_STATE_IN_SETUP
1667 || call->state == CHAN_LCR_STATE_IN_DIALING) {
1668 /* send message to lcr */
1669 memset(&newparam, 0, sizeof(union parameter));
1670 send_message(MESSAGE_PROCEEDING, call->ref, &newparam);
1672 call->state = CHAN_LCR_STATE_IN_PROCEEDING;
1675 case AST_CONTROL_RINGING:
1676 CDEBUG(call, ast, "Received indicate AST_CONTROL_RINGING from Asterisk.\n");
1677 ast_setstate(ast, AST_STATE_RINGING);
1678 if (call->state == CHAN_LCR_STATE_IN_SETUP
1679 || call->state == CHAN_LCR_STATE_IN_DIALING
1680 || call->state == CHAN_LCR_STATE_IN_PROCEEDING) {
1681 /* send message to lcr */
1682 memset(&newparam, 0, sizeof(union parameter));
1683 send_message(MESSAGE_ALERTING, call->ref, &newparam);
1685 call->state = CHAN_LCR_STATE_IN_ALERTING;
1689 CDEBUG(call, ast, "Received indicate -1.\n");
1693 case AST_CONTROL_VIDUPDATE:
1694 CDEBUG(call, ast, "Received indicate AST_CONTROL_VIDUPDATE.\n");
1697 case AST_CONTROL_HOLD:
1698 CDEBUG(call, ast, "Received indicate AST_CONTROL_HOLD from Asterisk.\n");
1699 /* send message to lcr */
1700 memset(&newparam, 0, sizeof(union parameter));
1701 newparam.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
1702 send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1704 case AST_CONTROL_UNHOLD:
1705 CDEBUG(call, ast, "Received indicate AST_CONTROL_UNHOLD from Asterisk.\n");
1706 /* send message to lcr */
1707 memset(&newparam, 0, sizeof(union parameter));
1708 newparam.notifyinfo.notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
1709 send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1713 CERROR(call, ast, "Received indicate from Asterisk with unknown condition %d.\n", cond);
1719 ast_mutex_unlock(&chan_lock);
1726 static int lcr_fixup(struct ast_channel *oldast, struct ast_channel *newast)
1728 struct chan_call *call;
1730 ast_mutex_lock(&chan_lock);
1731 call = oldast->tech_pvt;
1732 if ((unsigned long)call <= 1) {
1733 CERROR(NULL, oldast, "Received fixup from Asterisk, but no call instance exists.\n");
1734 ast_mutex_unlock(&chan_lock);
1738 CDEBUG(call, oldast, "Received fixup from Asterisk.\n");
1740 ast_mutex_lock(&chan_lock);
1745 * send_text asterisk
1747 static int lcr_send_text(struct ast_channel *ast, const char *text)
1749 struct chan_call *call;
1750 union parameter newparam;
1752 ast_mutex_lock(&chan_lock);
1753 call = ast->tech_pvt;
1754 if ((unsigned long)call <= 1) {
1755 CERROR(NULL, ast, "Received send_text from Asterisk, but no call instance exists.\n");
1756 ast_mutex_unlock(&chan_lock);
1760 CDEBUG(call, ast, "Received send_text from Asterisk. (text=%s)\n", text);
1761 memset(&newparam, 0, sizeof(union parameter));
1762 strncpy(newparam.notifyinfo.display, text, sizeof(newparam.notifyinfo.display)-1);
1763 send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1764 ast_mutex_lock(&chan_lock);
1771 enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
1772 struct ast_channel *ast2, int flags,
1773 struct ast_frame **fo,
1774 struct ast_channel **rc, int timeoutms)
1777 struct chan_call *call1, *call2;
1778 struct ast_channel *carr[2], *who;
1780 struct ast_frame *f;
1783 CDEBUG(NULL, NULL, "Received briding request from Asterisk.\n");
1785 /* join via dsp (if the channels are currently open) */
1786 ast_mutex_lock(&chan_lock);
1787 bridge_id = new_bridge_id();
1788 call1 = ast1->tech_pvt;
1789 call2 = ast2->tech_pvt;
1792 call1->bridge_id = bridge_id;
1793 if (call1->bchannel)
1794 bchannel_join(call1->bchannel, bridge_id);
1795 call1->bridge_call = call2;
1799 call2->bridge_id = bridge_id;
1800 if (call2->bchannel)
1801 bchannel_join(call2->bchannel, bridge_id);
1802 call2->bridge_call = call1;
1804 ast_mutex_unlock(&chan_lock);
1807 who = ast_waitfor_n(carr, 2, &to);
1810 CDEBUG(NULL, NULL, "Empty read on bridge, breaking out.\n");
1815 if (!f || f->frametype == AST_FRAME_CONTROL) {
1822 if ( f->frametype == AST_FRAME_DTMF ) {
1838 CDEBUG(NULL, NULL, "Releasing bride.\n");
1840 /* split channels */
1841 ast_mutex_lock(&chan_lock);
1842 call1 = ast1->tech_pvt;
1843 call2 = ast2->tech_pvt;
1846 call1->bridge_id = 0;
1847 if (call1->bchannel)
1848 bchannel_join(call1->bchannel, 0);
1849 if (call1->bridge_call)
1850 call1->bridge_call->bridge_call = NULL;
1851 call1->bridge_call = NULL;
1855 call2->bridge_id = 0;
1856 if (call2->bchannel)
1857 bchannel_join(call2->bchannel, 0);
1858 if (call2->bridge_call)
1859 call2->bridge_call->bridge_call = NULL;
1860 call2->bridge_call = NULL;
1862 ast_mutex_unlock(&chan_lock);
1865 return AST_BRIDGE_COMPLETE;
1867 static struct ast_channel_tech lcr_tech = {
1869 .description="Channel driver for connecting to Linux-Call-Router",
1873 .capabilities=AST_FORMAT_ALAW,
1875 .requester=lcr_request,
1876 .send_digit_begin=lcr_digit,
1883 .indicate=lcr_indicate,
1885 .send_text=lcr_send_text,
1893 static int lcr_show_lcr (int fd, int argc, char *argv[])
1898 static int lcr_show_calls (int fd, int argc, char *argv[])
1903 static int lcr_reload_routing (int fd, int argc, char *argv[])
1908 static int lcr_reload_interfaces (int fd, int argc, char *argv[])
1913 static int lcr_port_block (int fd, int argc, char *argv[])
1918 static int lcr_port_unblock (int fd, int argc, char *argv[])
1923 static int lcr_port_unload (int fd, int argc, char *argv[])
1928 static struct ast_cli_entry cli_show_lcr =
1929 { {"lcr", "show", "lcr", NULL},
1931 "Shows current states of LCR core",
1932 "Usage: lcr show lcr\n",
1935 static struct ast_cli_entry cli_show_calls =
1936 { {"lcr", "show", "calls", NULL},
1938 "Shows current calls made by LCR and Asterisk",
1939 "Usage: lcr show calls\n",
1942 static struct ast_cli_entry cli_reload_routing =
1943 { {"lcr", "reload", "routing", NULL},
1945 "Reloads routing conf of LCR, current uncomplete calls will be disconnected",
1946 "Usage: lcr reload routing\n",
1949 static struct ast_cli_entry cli_reload_interfaces =
1950 { {"lcr", "reload", "interfaces", NULL},
1951 lcr_reload_interfaces,
1952 "Reloads interfaces conf of LCR",
1953 "Usage: lcr reload interfaces\n",
1956 static struct ast_cli_entry cli_port_block =
1957 { {"lcr", "port", "block", NULL},
1959 "Blocks LCR port for further calls",
1960 "Usage: lcr port block \"<port>\"\n",
1963 static struct ast_cli_entry cli_port_unblock =
1964 { {"lcr", "port", "unblock", NULL},
1966 "Unblocks or loads LCR port, port is opened my mISDN",
1967 "Usage: lcr port unblock \"<port>\"\n",
1970 static struct ast_cli_entry cli_port_unload =
1971 { {"lcr", "port", "unload", NULL},
1973 "Unloads LCR port, port is closes by mISDN",
1974 "Usage: lcr port unload \"<port>\"\n",
1979 * module loading and destruction
1981 int load_module(void)
1985 for (i = 0; i < 256; i++) {
1986 flip_bits[i] = (i>>7) | ((i>>5)&2) | ((i>>3)&4) | ((i>>1)&8)
1987 | (i<<7) | ((i&2)<<5) | ((i&4)<<3) | ((i&8)<<1);
1990 ast_mutex_init(&chan_lock);
1991 ast_mutex_init(&log_lock);
1993 if (open_socket() < 0) {
1994 /* continue with closed socket */
1997 if (bchannel_initialize()) {
1998 CERROR(NULL, NULL, "Unable to open mISDN device\n");
2000 return AST_MODULE_LOAD_DECLINE;
2004 if (ast_channel_register(&lcr_tech)) {
2005 CERROR(NULL, NULL, "Unable to register channel class\n");
2006 bchannel_deinitialize();
2008 return AST_MODULE_LOAD_DECLINE;
2012 ast_cli_register(&cli_show_lcr);
2013 ast_cli_register(&cli_show_calls);
2015 ast_cli_register(&cli_reload_routing);
2016 ast_cli_register(&cli_reload_interfaces);
2017 ast_cli_register(&cli_port_block);
2018 ast_cli_register(&cli_port_unblock);
2019 ast_cli_register(&cli_port_unload);
2021 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
2022 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
2023 "Sets mISDN opts. and optargs\n"
2025 "The available options are:\n"
2026 " d - Send display text on called phone, text is the optparam\n"
2027 " n - don't detect dtmf tones on called channel\n"
2028 " h - make digital outgoing call\n"
2029 " c - make crypted outgoing call, param is keyindex\n"
2030 " e - perform echo cancelation on this channel,\n"
2031 " takes taps as arguments (32,64,128,256)\n"
2032 " s - send Non Inband DTMF as inband\n"
2033 " vr - rxgain control\n"
2034 " vt - txgain control\n"
2038 lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
2041 //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
2045 if ((pthread_create(&chan_tid, NULL, chan_thread, NULL)<0))
2047 /* failed to create thread */
2048 bchannel_deinitialize();
2050 ast_channel_unregister(&lcr_tech);
2051 return AST_MODULE_LOAD_DECLINE;
2056 int unload_module(void)
2058 /* First, take us out of the channel loop */
2059 CDEBUG(NULL, NULL, "-- Unregistering mISDN Channel Driver --\n");
2062 pthread_join(chan_tid, NULL);
2064 ast_channel_unregister(&lcr_tech);
2066 if (mISDN_created) {
2067 bchannel_deinitialize();
2071 if (lcr_sock >= 0) {
2079 int reload_module(void)
2089 ast_mutex_t usecnt_lock;
2094 ast_mutex_lock(&usecnt_lock);
2096 ast_mutex_unlock(&usecnt_lock);
2101 char *desc="Channel driver for lcr";
2103 char *description(void)
2110 return ASTERISK_GPL_KEY;
2114 #define AST_MODULE "chan_lcr"
2116 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Channel driver for Linux-Call-Router Support (ISDN BRI/PRI)",
2117 .load = load_module,
2118 .unload = unload_module,
2119 .reload = reload_module,