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 requested from Asterisk, a new chan_call instance is created.
35 The new Asterisk instance pointer (ast) is stored to chan_call structure.
36 The current call ref is set to 0, the state is CHAN_LCR_STATE_OUT_PREPARE.
37 If the call is received (lcr_call) A MESSASGE_NEWREF is sent to LCR requesting
38 a new call reference (ref).
39 Further dialing information is queued.
40 After the new callref is received by special MESSAGE_NEWREF reply, new ref
41 is stored in the chan_call structure.
42 The setup information is sent to LCR using MESSAGE_SETUP.
43 The state changes to CHAN_LCR_STATE_OUT_SETUP.
48 During call process, messages are received and sent.
49 The state changes accordingly.
50 Any message is allowed to be sent to LCR at any time except MESSAGE_RELEASE.
51 If a MESSAGE_OVERLAP is received, further dialing is required.
52 Queued dialing information, if any, is sent to LCR using MESSAGE_DIALING.
53 In this case, the state changes to CHAN_LCR_STATE_OUT_DIALING.
56 Call is released by LCR:
58 A MESSAGE_RELEASE is received with the call reference (ref) to be released.
59 The current ref is set to 0, to indicate released reference.
60 The state changes to CHAN_LCR_STATE_RELEASE.
61 ast_queue_hangup() is called, if asterisk instance (ast) exists, if not,
62 the chan_call instance is destroyed.
63 After lcr_hangup() is called-back by Asterisk, the chan_call instance
64 is destroyed, because the current ref is set to 0 and the state equals
65 CHAN_LCR_STATE_RELEASE.
66 If the ref is 0 and the state is not CHAN_LCR_STATE_RELEASE, see the proceedure
67 "Call is released by Asterisk".
70 Call is released by Asterisk:
72 lcr_hangup() is called-back by Asterisk. If the call reference (ref) is set,
73 a MESSAGE_RELEASE is sent to LCR and the chan_call instance is destroyed.
74 If the ref is 0 and the state is not CHAN_LCR_STATE_RELEASE, the new state is
75 set to CHAN_LCR_STATE_RELEASE.
76 Later, if the MESSAGE_NEWREF reply is received, a MESSAGE_RELEASE is sent to
77 LCR and the chan_call instance is destroyed.
78 If the ref is 0 and the state is CHAN_LCR_STATE_RELEASE, see the proceedure
79 "Call is released by LCR".
88 #include <sys/types.h>
93 #include <sys/ioctl.h>
94 #include <sys/socket.h>
97 #include <semaphore.h>
99 #include <asterisk/module.h>
100 #include <asterisk/channel.h>
101 #include <asterisk/config.h>
102 #include <asterisk/logger.h>
103 #include <asterisk/pbx.h>
104 #include <asterisk/options.h>
105 #include <asterisk/io.h>
106 #include <asterisk/frame.h>
107 #include <asterisk/translate.h>
108 #include <asterisk/cli.h>
109 #include <asterisk/musiconhold.h>
110 #include <asterisk/dsp.h>
111 #include <asterisk/translate.h>
112 #include <asterisk/file.h>
113 #include <asterisk/callerid.h>
114 #include <asterisk/indications.h>
115 #include <asterisk/app.h>
116 #include <asterisk/features.h>
117 #include <asterisk/sched.h>
119 #include "extension.h"
121 #include "callerid.h"
122 #include "lcrsocket.h"
124 #include "bchannel.h"
126 #include "chan_lcr.h"
128 CHAN_LCR_STATE // state description structure
129 MESSAGES // message text
131 unsigned char flip_bits[256];
136 char lcr_type[]="lcr";
139 ast_mutex_t chan_lock; /* global lock */
140 ast_mutex_t log_lock; /* logging log */
143 int glob_channel = 0;
148 struct admin_list *next;
149 struct admin_message msg;
150 } *admin_first = NULL;
152 static struct ast_channel_tech lcr_tech;
157 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, ...)
160 char call_text[128] = "NULL";
161 char ast_text[128] = "NULL";
164 ast_mutex_lock(&log_lock);
167 vsnprintf(buffer,sizeof(buffer)-1,fmt,args);
168 buffer[sizeof(buffer)-1]=0;
172 sprintf(call_text, "%ld", call->ref);
174 strncpy(ast_text, ast->name, sizeof(ast_text)-1);
175 ast_text[sizeof(ast_text)-1] = '\0';
177 ast_log(type, file, line, function, "[call=%s ast=%s] %s", call_text, ast_text, buffer);
179 ast_mutex_unlock(&log_lock);
183 * channel and call instances
185 struct chan_call *call_first;
187 struct chan_call *find_call_ref(unsigned long ref)
189 struct chan_call *call = call_first;
193 if (call->ref == ref)
201 struct chan_call *find_call_ast(struct ast_channel *ast)
203 struct chan_call *call = call_first;
207 if (call->ast == ast)
214 struct chan_call *find_call_handle(unsigned long handle)
216 struct chan_call *call = call_first;
220 if (call->bchannel_handle == handle)
228 void free_call(struct chan_call *call)
230 struct chan_call **temp = &call_first;
236 *temp = (*temp)->next;
237 if (call->pipe[0] > -1)
238 close(call->pipe[0]);
239 if (call->pipe[1] > -1)
240 close(call->pipe[1]);
243 if (call->bchannel->call != call)
244 CERROR(call, NULL, "Linked bchannel structure has no link to us.\n");
245 call->bchannel->call = NULL;
247 if (call->bridge_call)
249 if (call->bridge_call->bridge_call != call)
250 CERROR(call, NULL, "Linked call structure has no link to us.\n");
251 call->bridge_call->bridge_call = NULL;
253 CDEBUG(call, NULL, "Call instance freed.\n");
257 temp = &((*temp)->next);
259 CERROR(call, NULL, "Call instance not found in list.\n");
262 struct chan_call *alloc_call(void)
264 struct chan_call **callp = &call_first;
267 callp = &((*callp)->next);
269 *callp = (struct chan_call *)calloc(1, sizeof(struct chan_call));
271 memset(*callp, 0, sizeof(struct chan_call));
272 if (pipe((*callp)->pipe) < 0) {
273 CERROR(*callp, NULL, "Failed to create pipe.\n");
277 CDEBUG(*callp, NULL, "Call instance allocated.\n");
282 unsigned short new_bridge_id(void)
284 struct chan_call *call;
285 unsigned short id = 1;
287 /* search for lowest bridge id that is not in use and not 0 */
293 if (call->bridge_id == id)
301 CDEBUG(NULL, NULL, "New bridge ID %d.\n", id);
307 * enque message to LCR
309 int send_message(int message_type, unsigned long ref, union parameter *param)
311 struct admin_list *admin, **adminp;
314 CDEBUG(NULL, NULL, "Ignoring message %d, because socket is closed.\n", message_type);
317 CDEBUG(NULL, NULL, "Sending %s to socket.\n", messages_txt[message_type]);
319 adminp = &admin_first;
321 adminp = &((*adminp)->next);
322 admin = (struct admin_list *)calloc(1, sizeof(struct admin_list));
324 CERROR(NULL, NULL, "No memory for message to LCR.\n");
329 admin->msg.message = ADMIN_MESSAGE;
330 admin->msg.u.msg.type = message_type;
331 admin->msg.u.msg.ref = ref;
332 memcpy(&admin->msg.u.msg.param, param, sizeof(union parameter));
338 * send setup info to LCR
339 * this function is called, when asterisk call is received and ref is received
341 static void send_setup_to_lcr(struct chan_call *call)
343 union parameter newparam;
344 struct ast_channel *ast = call->ast;
346 if (!call->ast || !call->ref)
349 CDEBUG(call, call->ast, "Sending setup to LCR. (interface=%s dialstring=%s)\n", call->interface, call->dialstring);
351 /* send setup message to LCR */
352 memset(&newparam, 0, sizeof(union parameter));
353 newparam.setup.dialinginfo.itype = INFO_ITYPE_ISDN;
354 newparam.setup.dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
355 strncpy(newparam.setup.dialinginfo.id, call->dialstring, sizeof(newparam.setup.dialinginfo.id)-1);
356 strncpy(newparam.setup.dialinginfo.interfaces, call->interface, sizeof(newparam.setup.dialinginfo.interfaces)-1);
357 newparam.setup.callerinfo.itype = INFO_ITYPE_CHAN;
358 newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
359 if (ast->cid.cid_num) if (ast->cid.cid_num[0])
360 strncpy(newparam.setup.callerinfo.id, ast->cid.cid_num, sizeof(newparam.setup.callerinfo.id)-1);
361 if (ast->cid.cid_name) if (ast->cid.cid_name[0])
362 strncpy(newparam.setup.callerinfo.name, ast->cid.cid_name, sizeof(newparam.setup.callerinfo.name)-1);
363 if (ast->cid.cid_rdnis) if (ast->cid.cid_rdnis[0])
365 strncpy(newparam.setup.redirinfo.id, ast->cid.cid_rdnis, sizeof(newparam.setup.redirinfo.id)-1);
366 newparam.setup.redirinfo.itype = INFO_ITYPE_CHAN;
367 newparam.setup.redirinfo.ntype = INFO_NTYPE_UNKNOWN;
369 switch(ast->cid.cid_pres & AST_PRES_RESTRICTION)
371 case AST_PRES_ALLOWED:
372 newparam.setup.callerinfo.present = INFO_PRESENT_ALLOWED;
374 case AST_PRES_RESTRICTED:
375 newparam.setup.callerinfo.present = INFO_PRESENT_RESTRICTED;
377 case AST_PRES_UNAVAILABLE:
378 newparam.setup.callerinfo.present = INFO_PRESENT_NOTAVAIL;
381 newparam.setup.callerinfo.present = INFO_PRESENT_NULL;
383 switch(ast->cid.cid_ton)
386 newparam.setup.callerinfo.ntype = INFO_NTYPE_SUBSCRIBER;
389 newparam.setup.callerinfo.ntype = INFO_NTYPE_NATIONAL;
392 newparam.setup.callerinfo.ntype = INFO_NTYPE_INTERNATIONAL;
395 newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
397 newparam.setup.capainfo.bearer_capa = ast->transfercapability;
398 newparam.setup.capainfo.bearer_info1 = (options.law=='a')?3:2;
399 newparam.setup.capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
400 newparam.setup.capainfo.hlc = INFO_HLC_NONE;
401 newparam.setup.capainfo.exthlc = INFO_HLC_NONE;
402 send_message(MESSAGE_SETUP, call->ref, &newparam);
404 /* change to outgoing setup state */
405 call->state = CHAN_LCR_STATE_OUT_SETUP;
409 * send dialing info to LCR
410 * this function is called, when setup acknowledge is received and dialing
413 static void send_dialque_to_lcr(struct chan_call *call)
415 union parameter newparam;
417 if (!call->ast || !call->ref || !call->dialque[0])
420 CDEBUG(call, call->ast, "Sending dial queue to LCR. (dialing=%s)\n", call->dialque);
422 /* send setup message to LCR */
423 memset(&newparam, 0, sizeof(union parameter));
424 strncpy(newparam.information.id, call->dialque, sizeof(newparam.information.id)-1);
425 call->dialque[0] = '\0';
426 send_message(MESSAGE_INFORMATION, call->ref, &newparam);
430 * in case of a bridge, the unsupported message can be forwarded directly
431 * to the remote call.
433 static void bridge_message_if_bridged(struct chan_call *call, int message_type, union parameter *param)
437 if (!call->bridge_call) return;
438 CDEBUG(call, NULL, "Sending message due briding.\n");
439 send_message(message_type, call->bridge_call->ref, param);
443 * send release message to LCR and import bchannel if exported
445 static void send_release_and_import(struct chan_call *call, int cause, int location)
447 union parameter newparam;
449 /* importing channel */
450 if (call->bchannel) {
451 memset(&newparam, 0, sizeof(union parameter));
452 newparam.bchannel.type = BCHANNEL_RELEASE;
453 newparam.bchannel.handle = call->bchannel->handle;
454 send_message(MESSAGE_BCHANNEL, call->ref, &newparam);
456 /* sending release */
457 memset(&newparam, 0, sizeof(union parameter));
458 newparam.disconnectinfo.cause = cause;
459 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
460 send_message(MESSAGE_RELEASE, call->ref, &newparam);
464 * check if extension matches and start asterisk
465 * if it can match, proceed
468 static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int complete)
471 union parameter newparam;
473 CDEBUG(call, ast, "Try to start pbx. (exten=%s context=%s complete=%s)\n", ast->exten, ast->context, complete?"yes":"no");
478 if (!ast_canmatch_extension(ast, ast->context, ast->exten, 1, call->oad))
480 CDEBUG(call, ast, "Got 'sending complete', but extension '%s' will not match at context '%s' - releasing.\n", ast->exten, ast->context);
484 if (!ast_exists_extension(ast, ast->context, ast->exten, 1, call->oad))
486 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);
490 CDEBUG(call, ast, "Got 'sending complete', extensions matches.\n");
491 /* send setup acknowledge to lcr */
492 memset(&newparam, 0, sizeof(union parameter));
493 send_message(MESSAGE_PROCEEDING, call->ref, &newparam);
496 call->state = CHAN_LCR_STATE_IN_PROCEEDING;
501 if (ast_canmatch_extension(ast, ast->context, ast->exten, 1, call->oad))
503 /* send setup acknowledge to lcr */
504 if (call->state != CHAN_LCR_STATE_IN_DIALING) {
505 memset(&newparam, 0, sizeof(union parameter));
506 send_message(MESSAGE_OVERLAP, call->ref, &newparam);
510 call->state = CHAN_LCR_STATE_IN_DIALING;
512 /* if match, start pbx */
513 if (ast_exists_extension(ast, ast->context, ast->exten, 1, call->oad)) {
514 CDEBUG(call, ast, "Extensions matches.\n");
519 CDEBUG(call, ast, "Extensions may match, if more digits are dialed.\n");
527 CDEBUG(call, ast, "Releasing due to extension missmatch.\n");
528 send_release_and_import(call, cause, LOCATION_PRIVATE_LOCAL);
530 /* release asterisk */
531 ast->hangupcause = call->cause;
532 /* change to release state */
533 call->state = CHAN_LCR_STATE_RELEASE;
534 ast_hangup(ast); // call will be destroyed here
538 /* send setup to asterisk */
539 CDEBUG(call, ast, "Starting call to Asterisk due to matching extension.\n");
540 ret = ast_pbx_start(ast);
543 cause = (ret==-2)?34:27;
546 call->pbx_started = 1;
551 * incoming setup from LCR
553 static void lcr_in_setup(struct chan_call *call, int message_type, union parameter *param)
555 struct ast_channel *ast;
557 CDEBUG(call, NULL, "Incomming setup from LCR. (callerid %s, dialing %s)\n", param->setup.callerinfo.id, param->setup.dialinginfo.id);
559 /* create asterisk channel instrance */
560 ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
564 CERROR(call, NULL, "Failed to create Asterisk channel - releasing.\n");
565 send_release_and_import(call, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL);
572 ast->tech_pvt = call;
573 ast->tech = &lcr_tech;
574 ast->fds[0] = call->pipe[0];
576 /* fill setup information */
577 if (param->setup.dialinginfo.id)
578 strncpy(ast->exten, param->setup.dialinginfo.id, AST_MAX_EXTENSION-1);
579 if (param->setup.context[0])
580 strncpy(ast->context, param->setup.context, AST_MAX_CONTEXT-1);
582 strncpy(ast->context, param->setup.callerinfo.interface, AST_MAX_CONTEXT-1);
583 if (param->setup.callerinfo.id[0])
584 ast->cid.cid_num = strdup(param->setup.callerinfo.id);
585 if (param->setup.callerinfo.name[0])
586 ast->cid.cid_name = strdup(param->setup.callerinfo.name);
587 if (param->setup.redirinfo.id[0])
588 ast->cid.cid_name = strdup(numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, options.national, options.international));
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;
615 strncpy(call->oad, numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, options.national, options.international), sizeof(call->oad)-1);
617 /* configure channel */
618 ast->nativeformats = (options.law=='a')?AST_FORMAT_ALAW:AST_FORMAT_ULAW;
619 ast->readformat = ast->rawreadformat = ast->nativeformats;
620 ast->writeformat = ast->rawwriteformat = ast->nativeformats;
622 ast->hangupcause = 0;
625 call->state = CHAN_LCR_STATE_IN_SETUP;
627 lcr_start_pbx(call, ast, param->setup.dialinginfo.sending_complete);
631 * incoming setup acknowledge from LCR
633 static void lcr_in_overlap(struct chan_call *call, int message_type, union parameter *param)
635 if (!call->ast) return;
637 CDEBUG(call, call->ast, "Incomming setup acknowledge from LCR.\n");
639 /* send pending digits in dialque */
640 if (call->dialque[0])
641 send_dialque_to_lcr(call);
642 /* change to overlap state */
643 call->state = CHAN_LCR_STATE_OUT_DIALING;
647 * incoming proceeding from LCR
649 static void lcr_in_proceeding(struct chan_call *call, int message_type, union parameter *param)
651 CDEBUG(call, call->ast, "Incomming proceeding from LCR.\n");
654 call->state = CHAN_LCR_STATE_OUT_PROCEEDING;
655 /* send event to asterisk */
656 if (call->ast && call->pbx_started)
657 ast_queue_control(call->ast, AST_CONTROL_PROCEEDING);
661 * incoming alerting from LCR
663 static void lcr_in_alerting(struct chan_call *call, int message_type, union parameter *param)
665 CDEBUG(call, call->ast, "Incomming alerting from LCR.\n");
668 call->state = CHAN_LCR_STATE_OUT_ALERTING;
669 /* send event to asterisk */
670 if (call->ast && call->pbx_started)
671 ast_queue_control(call->ast, AST_CONTROL_RINGING);
675 * incoming connect from LCR
677 static void lcr_in_connect(struct chan_call *call, int message_type, union parameter *param)
679 union parameter newparam;
681 CDEBUG(call, call->ast, "Incomming connect (answer) from LCR.\n");
684 call->state = CHAN_LCR_STATE_CONNECT;
685 /* request bchannel */
686 if (!call->bchannel) {
687 CDEBUG(call, call->ast, "Requesting B-channel.\n");
688 memset(&newparam, 0, sizeof(union parameter));
689 newparam.bchannel.type = BCHANNEL_REQUEST;
690 send_message(MESSAGE_BCHANNEL, call->ref, &newparam);
692 /* copy connectinfo */
693 memcpy(&call->connectinfo, ¶m->connectinfo, sizeof(struct connect_info));
694 /* send event to asterisk */
695 if (call->ast && call->pbx_started)
696 ast_queue_control(call->ast, AST_CONTROL_ANSWER);
700 * incoming disconnect from LCR
702 static void lcr_in_disconnect(struct chan_call *call, int message_type, union parameter *param)
704 struct ast_channel *ast = call->ast;
706 CDEBUG(call, call->ast, "Incomming disconnect from LCR. (cause=%d)\n", param->disconnectinfo.cause);
709 call->state = CHAN_LCR_STATE_IN_DISCONNECT;
711 call->cause = param->disconnectinfo.cause;
712 call->location = param->disconnectinfo.location;
713 /* if bridge, forward disconnect and return */
716 if (call->bridge_call)
718 CDEBUG(call, call->ast, "Only signal disconnect via bridge.\n");
719 bridge_message_if_bridged(call, message_type, param);
723 /* release lcr with same cause */
724 send_release_and_import(call, call->cause, call->location);
726 /* change to release state */
727 call->state = CHAN_LCR_STATE_RELEASE;
728 /* release asterisk */
731 ast->hangupcause = call->cause;
732 if (call->pbx_started)
733 ast_queue_hangup(ast);
735 ast_hangup(ast); // call will be destroyed here
741 * incoming setup acknowledge from LCR
743 static void lcr_in_release(struct chan_call *call, int message_type, union parameter *param)
745 struct ast_channel *ast = call->ast;
747 CDEBUG(call, call->ast, "Incomming release from LCR, releasing ref. (cause=%d)\n", param->disconnectinfo.cause);
751 /* change to release state */
752 call->state = CHAN_LCR_STATE_RELEASE;
753 /* copy release info */
756 call->cause = param->disconnectinfo.cause;
757 call->location = param->disconnectinfo.location;
759 /* if we have an asterisk instance, send hangup, else we are done */
762 ast->hangupcause = call->cause;
763 if (call->pbx_started)
764 ast_queue_hangup(ast);
766 ast_hangup(ast); // call will be destroyed here
776 * incoming information from LCR
778 static void lcr_in_information(struct chan_call *call, int message_type, union parameter *param)
780 struct ast_channel *ast = call->ast;
784 CDEBUG(call, call->ast, "Incoming information from LCR. (dialing=%s)\n", param->information.id);
788 /* pbx not started */
789 if (!call->pbx_started)
791 CDEBUG(call, call->ast, "Asterisk not started, adding digits to number.\n");
792 strncat(ast->exten, param->information.id, AST_MAX_EXTENSION-1);
793 lcr_start_pbx(call, ast, param->information.sending_complete);
798 p = param->information.id;
799 if (call->state == CHAN_LCR_STATE_IN_DIALING && *p)
801 CDEBUG(call, call->ast, "Asterisk is started, sending DTMF frame.\n");
804 /* send digit to asterisk */
805 memset(&fr, 0, sizeof(fr));
806 fr.frametype = AST_FRAME_DTMF;
808 fr.delivery = ast_tv(0, 0);
809 ast_queue_frame(call->ast, &fr);
813 /* use bridge to forware message not supported by asterisk */
814 if (call->state == CHAN_LCR_STATE_CONNECT) {
815 CDEBUG(call, call->ast, "Call is connected, briding.\n");
816 bridge_message_if_bridged(call, message_type, param);
821 * incoming information from LCR
823 static void lcr_in_notify(struct chan_call *call, int message_type, union parameter *param)
825 CDEBUG(call, call->ast, "Incomming notify from LCR. (notify=%d)\n", param->notifyinfo.notify);
827 if (!call->ast) return;
829 /* use bridge to forware message not supported by asterisk */
830 bridge_message_if_bridged(call, message_type, param);
834 * incoming information from LCR
836 static void lcr_in_facility(struct chan_call *call, int message_type, union parameter *param)
838 CDEBUG(call, call->ast, "Incomming facility from LCR.\n");
840 if (!call->ast) return;
842 /* use bridge to forware message not supported by asterisk */
843 bridge_message_if_bridged(call, message_type, param);
847 * got dtmf from bchannel
849 void lcr_in_dtmf(struct chan_call *call, int val)
851 struct ast_channel *ast = call->ast;
856 if (!call->pbx_started)
859 CDEBUG(call, call->ast, "Frowarding DTMF digit '%c' to Asterisk.\n", val);
861 /* send digit to asterisk */
862 memset(&fr, 0, sizeof(fr));
863 fr.frametype = AST_FRAME_DTMF;
865 fr.delivery = ast_tv(0, 0);
866 ast_queue_frame(call->ast, &fr);
870 * message received from LCR
872 int receive_message(int message_type, unsigned long ref, union parameter *param)
874 struct bchannel *bchannel;
875 struct chan_call *call;
876 union parameter newparam;
878 memset(&newparam, 0, sizeof(union parameter));
880 /* handle bchannel message*/
881 if (message_type == MESSAGE_BCHANNEL)
883 switch(param->bchannel.type)
885 case BCHANNEL_ASSIGN:
886 CDEBUG(NULL, NULL, "Received BCHANNEL_ASSIGN message. (handle=%08lx)\n", param->bchannel.handle);
887 if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
889 CERROR(NULL, NULL, "bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
892 /* create bchannel */
893 bchannel = alloc_bchannel(param->bchannel.handle);
896 CERROR(NULL, NULL, "alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
900 /* configure channel */
901 bchannel->b_tx_gain = param->bchannel.tx_gain;
902 bchannel->b_rx_gain = param->bchannel.rx_gain;
903 strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
904 if (param->bchannel.crypt_len)
906 bchannel->b_crypt_len = param->bchannel.crypt_len;
907 bchannel->b_crypt_type = param->bchannel.crypt_type;
908 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
910 bchannel->b_txdata = 0;
911 bchannel->b_dtmf = 1;
912 bchannel->b_tx_dejitter = 1;
914 /* in case, ref is not set, this bchannel instance must
915 * be created until it is removed again by LCR */
917 call = find_call_ref(ref);
920 bchannel->call = call;
921 call->bchannel = bchannel;
923 bchannel_dtmf(bchannel, 1);
925 hier muesen alle bchannel-features gesetzt werden (pipeline...) falls sie vor dem b-kanal verfügbar waren
927 if (call->bridge_id) {
928 CDEBUG(call, call->ast, "Join bchannel, because call is already bridged.\n");
929 bchannel_join(bchannel, call->bridge_id);
932 if (bchannel_create(bchannel))
933 bchannel_activate(bchannel, 1);
935 newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
936 newparam.bchannel.handle = param->bchannel.handle;
937 send_message(MESSAGE_BCHANNEL, 0, &newparam);
938 /* if call has released before bchannel is assigned */
940 newparam.bchannel.type = BCHANNEL_RELEASE;
941 newparam.bchannel.handle = param->bchannel.handle;
942 send_message(MESSAGE_BCHANNEL, 0, &newparam);
947 case BCHANNEL_REMOVE:
948 CDEBUG(NULL, NULL, "Received BCHANNEL_REMOVE message. (handle=%08lx)\n", param->bchannel.handle);
949 if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
951 CERROR(NULL, NULL, "Bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
954 /* unklink from call and destroy bchannel */
955 free_bchannel(bchannel);
958 newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
959 newparam.bchannel.handle = param->bchannel.handle;
960 send_message(MESSAGE_BCHANNEL, 0, &newparam);
965 CDEBUG(NULL, NULL, "Received unknown bchannel message %d.\n", param->bchannel.type);
971 if (message_type == MESSAGE_NEWREF)
973 if (param->direction)
975 /* new ref from lcr */
976 CDEBUG(NULL, NULL, "Received new ref by LCR, due to incomming call. (ref=%ld)\n", ref);
977 if (!ref || find_call_ref(ref))
979 CERROR(NULL, NULL, "Illegal new ref %ld received.\n", ref);
982 /* allocate new call instance */
985 call->state = CHAN_LCR_STATE_IN_PREPARE;
988 /* wait for setup (or release from asterisk) */
991 /* new ref, as requested from this remote application */
992 CDEBUG(NULL, NULL, "Received new ref by LCR, as requested from chan_lcr. (ref=%ld)\n", ref);
993 call = find_call_ref(0);
996 /* send release, if ref does not exist */
997 CDEBUG(NULL, NULL, "No call found, that requests a ref.\n");
998 send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL);
1003 /* send pending setup info */
1004 if (call->state == CHAN_LCR_STATE_OUT_PREPARE)
1005 send_setup_to_lcr(call);
1006 /* release if asterisk has signed off */
1007 else if (call->state == CHAN_LCR_STATE_RELEASE)
1011 send_release_and_import(call, call->cause, call->location);
1013 send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL);
1025 CERROR(NULL, NULL, "Received message %d without ref.\n", message_type);
1028 call = find_call_ref(ref);
1031 /* ignore ref that is not used (anymore) */
1032 CDEBUG(NULL, NULL, "Message %d from LCR ignored, because no call instance found.\n", message_type);
1036 /* handle messages */
1037 switch(message_type)
1040 lcr_in_setup(call, message_type, param);
1043 case MESSAGE_OVERLAP:
1044 lcr_in_overlap(call, message_type, param);
1047 case MESSAGE_PROCEEDING:
1048 lcr_in_proceeding(call, message_type, param);
1051 case MESSAGE_ALERTING:
1052 lcr_in_alerting(call, message_type, param);
1055 case MESSAGE_CONNECT:
1056 lcr_in_connect(call, message_type, param);
1059 case MESSAGE_DISCONNECT:
1060 lcr_in_disconnect(call, message_type, param);
1063 case MESSAGE_RELEASE:
1064 lcr_in_release(call, message_type, param);
1067 case MESSAGE_INFORMATION:
1068 lcr_in_information(call, message_type, param);
1071 case MESSAGE_NOTIFY:
1072 lcr_in_notify(call, message_type, param);
1075 case MESSAGE_FACILITY:
1076 lcr_in_facility(call, message_type, param);
1079 case MESSAGE_PATTERN: // audio available from LCR
1082 case MESSAGE_NOPATTERN: // audio not available from LCR
1085 case MESSAGE_AUDIOPATH: // if remote audio connected or hold
1086 call->audiopath = param->audiopath;
1090 CDEBUG(call, call->ast, "Message %d from LCR unhandled.\n", message_type);
1097 * release all calls (due to broken socket)
1099 static void release_all_calls(void)
1101 struct chan_call *call;
1106 /* no ast, so we may directly free call */
1108 CDEBUG(call, NULL, "Freeing call, because no Asterisk channel is linked.\n");
1112 /* already in release process */
1113 if (call->state == CHAN_LCR_STATE_RELEASE) {
1117 /* release or queue release */
1119 call->state = CHAN_LCR_STATE_RELEASE;
1120 if (!call->pbx_started) {
1121 CDEBUG(call, call->ast, "Releasing call, because no Asterisk channel is not started.\n");
1122 ast_hangup(call->ast); // call will be destroyed here
1125 CDEBUG(call, call->ast, "Queue call release, because Asterisk channel is running.\n");
1126 ast_queue_hangup(call->ast);
1130 /* release all bchannels */
1131 while(bchannel_first)
1132 free_bchannel(bchannel_first);
1137 * warning! not thread safe
1138 * returns -1 for socket error, 0 for no work, 1 for work
1140 int handle_socket(void)
1144 struct admin_list *admin;
1145 struct admin_message msg;
1147 /* read from socket */
1148 len = read(lcr_sock, &msg, sizeof(msg));
1151 CERROR(NULL, NULL, "Socket closed.\n");
1152 return(-1); // socket closed
1156 if (len != sizeof(msg))
1158 CERROR(NULL, NULL, "Socket short read. (len %d)\n", len);
1159 return(-1); // socket error
1161 if (msg.message != ADMIN_MESSAGE)
1163 CERROR(NULL, NULL, "Socket received illegal message %d.\n", msg.message);
1166 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
1170 if (errno != EWOULDBLOCK)
1172 CERROR(NULL, NULL, "Socket failed (errno %d).\n", errno);
1177 /* write to socket */
1180 admin = admin_first;
1181 len = write(lcr_sock, &admin->msg, sizeof(msg));
1184 CERROR(NULL, NULL, "Socket closed.\n");
1185 return(-1); // socket closed
1189 if (len != sizeof(msg))
1191 CERROR(NULL, NULL, "Socket short write. (len %d)\n", len);
1192 return(-1); // socket error
1195 admin_first = admin->next;
1201 if (errno != EWOULDBLOCK)
1203 CERROR(NULL, NULL, "Socket failed (errno %d).\n", errno);
1212 * open and close socket and thread
1214 int open_socket(void)
1217 char *socket_name = SOCKET_NAME;
1219 struct sockaddr_un sock_address;
1220 unsigned long on = 1;
1221 union parameter param;
1224 if ((lcr_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1226 CERROR(NULL, NULL, "Failed to create socket.\n");
1230 /* set socket address and name */
1231 memset(&sock_address, 0, sizeof(sock_address));
1232 sock_address.sun_family = PF_UNIX;
1233 strcpy(sock_address.sun_path, socket_name);
1235 /* connect socket */
1236 if ((conn = connect(lcr_sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
1240 CDEBUG(NULL, NULL, "Failed to connect to socket '%s'. Is LCR running?\n", sock_address.sun_path);
1244 /* set non-blocking io */
1245 if ((ret = ioctl(lcr_sock, FIONBIO, (unsigned char *)(&on))) < 0)
1249 CERROR(NULL, NULL, "Failed to set socket into non-blocking IO.\n");
1253 /* enque hello message */
1254 memset(¶m, 0, sizeof(param));
1255 strcpy(param.hello.application, "asterisk");
1256 send_message(MESSAGE_HELLO, 0, ¶m);
1261 void close_socket(void)
1263 struct admin_list *admin, *temp;
1265 /* flush pending messages */
1266 admin = admin_first;
1269 admin = admin->next;
1280 void sighandler(int sigset)
1284 static void *chan_thread(void *arg)
1288 union parameter param;
1289 time_t retry = 0, now;
1291 bchannel_pid = getpid();
1293 // signal(SIGPIPE, sighandler);
1295 memset(¶m, 0, sizeof(union parameter));
1299 ast_mutex_lock(&chan_lock);
1306 ret = handle_socket();
1308 CERROR(NULL, NULL, "Handling of socket failed - closing for some seconds.\n");
1310 release_all_calls();
1317 if (retry && now-retry > 5) {
1318 CDEBUG(NULL, NULL, "Retry to open socket.\n");
1320 if (open_socket() < 0) {
1329 ret = bchannel_handle();
1334 ast_mutex_unlock(&chan_lock);
1336 ast_mutex_lock(&chan_lock);
1342 CERROR(NULL, NULL, "Thread exit.\n");
1344 ast_mutex_unlock(&chan_lock);
1346 // signal(SIGPIPE, SIG_DFL);
1352 * new asterisk instance
1355 struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
1357 char exten[256], *dial, *interface, *opt;
1358 struct ast_channel *ast;
1359 struct chan_call *call;
1361 ast_mutex_lock(&chan_lock);
1363 CDEBUG(NULL, NULL, "Received request from Asterisk. data=%s\n", (char *)data);
1365 /* if socket is closed */
1368 CERROR(NULL, NULL, "Rejecting call from Asterisk, because LCR not running.\n");
1372 /* create call instance */
1373 call = alloc_call();
1376 /* failed to create instance */
1380 /* create asterisk channel instrance */
1381 ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
1384 CERROR(NULL, NULL, "Failed to create Asterisk channel.\n");
1386 /* failed to create instance */
1389 ast->tech = &lcr_tech;
1390 ast->tech_pvt = (void *)1L; // set pointer or asterisk will not call
1391 /* configure channel */
1392 ast->nativeformats = (options.law=='a')?AST_FORMAT_ALAW:AST_FORMAT_ULAW;
1393 ast->readformat = ast->rawreadformat = ast->nativeformats;
1394 ast->writeformat = ast->rawwriteformat = ast->nativeformats;
1396 ast->hangupcause = 0;
1400 ast->tech_pvt = call;
1401 ast->fds[0] = call->pipe[0];
1402 ast_mutex_unlock(&chan_lock);
1403 call->pbx_started = 0;
1405 call->state = CHAN_LCR_STATE_OUT_PREPARE;
1408 * Extract interface, dialstring, options from data.
1411 * <interface>/<dialstring>
1412 * <interface>/<dialstring>/options
1414 strncpy(exten, (char *)data, sizeof(exten)-1);
1415 exten[sizeof(exten)-1] = '\0';
1416 if ((dial = strchr(exten, '/'))) {
1419 if ((opt = strchr(dial, '/')))
1428 strncpy(call->interface, interface, sizeof(call->interface)-1);
1429 strncpy(call->dialstring, dial, sizeof(call->dialstring)-1);
1431 #warning todo: parse options
1437 * call from asterisk
1439 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
1441 union parameter newparam;
1442 struct chan_call *call;
1444 ast_mutex_lock(&chan_lock);
1445 call = ast->tech_pvt;
1447 CERROR(NULL, ast, "Received call from Asterisk, but call instance does not exist.\n");
1448 ast_mutex_unlock(&chan_lock);
1452 CDEBUG(NULL, ast, "Received call from Asterisk.\n");
1454 /* pbx process is started */
1455 call->pbx_started = 1;
1456 /* send MESSAGE_NEWREF */
1457 memset(&newparam, 0, sizeof(union parameter));
1458 newparam.direction = 0; /* request from app */
1459 send_message(MESSAGE_NEWREF, 0, &newparam);
1461 ast_mutex_unlock(&chan_lock);
1465 static int lcr_digit(struct ast_channel *ast, char digit)
1467 struct chan_call *call;
1468 union parameter newparam;
1471 /* only pass IA5 number space */
1472 if (digit > 126 || digit < 32)
1475 ast_mutex_lock(&chan_lock);
1476 call = ast->tech_pvt;
1478 CERROR(NULL, ast, "Received digit from Asterisk, but no call instance exists.\n");
1479 ast_mutex_unlock(&chan_lock);
1483 CDEBUG(call, ast, "Received digit '%c' from Asterisk.\n", digit);
1485 /* send information or queue them */
1486 if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING)
1488 CDEBUG(call, ast, "Sending digit to LCR, because we are in dialing state.\n");
1489 memset(&newparam, 0, sizeof(union parameter));
1490 newparam.information.id[0] = digit;
1491 newparam.information.id[1] = '\0';
1492 send_message(MESSAGE_INFORMATION, call->ref, &newparam);
1495 && (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP))
1497 CDEBUG(call, ast, "Queue digits, because we are in setup/dialing state and have no ref yet.\n");
1499 strncat(call->dialque, buf, strlen(call->dialque)-1);
1502 ast_mutex_unlock(&chan_lock);
1507 static int lcr_answer(struct ast_channel *ast)
1509 union parameter newparam;
1510 struct chan_call *call;
1512 ast_mutex_lock(&chan_lock);
1513 call = ast->tech_pvt;
1515 CERROR(NULL, ast, "Received answer from Asterisk, but no call instance exists.\n");
1516 ast_mutex_unlock(&chan_lock);
1520 CDEBUG(call, ast, "Received answer from Asterisk.\n");
1522 /* copy connectinfo, if bridged */
1523 if (call->bridge_call)
1524 memcpy(&call->connectinfo, &call->bridge_call->connectinfo, sizeof(struct connect_info));
1525 /* send connect message to lcr */
1526 memset(&newparam, 0, sizeof(union parameter));
1527 memcpy(&newparam.connectinfo, &call->connectinfo, sizeof(struct connect_info));
1528 send_message(MESSAGE_CONNECT, call->ref, &newparam);
1530 call->state = CHAN_LCR_STATE_CONNECT;
1531 /* request bchannel */
1532 if (!call->bchannel) {
1533 CDEBUG(call, ast, "Requesting B-channel.\n");
1534 memset(&newparam, 0, sizeof(union parameter));
1535 newparam.bchannel.type = BCHANNEL_REQUEST;
1536 send_message(MESSAGE_BCHANNEL, call->ref, &newparam);
1539 // memset(&newparam, 0, sizeof(union parameter));
1540 // send_message(MESSAGE_ENABLEKEYPAD, call->ref, &newparam);
1543 ast_mutex_unlock(&chan_lock);
1547 static int lcr_hangup(struct ast_channel *ast)
1549 struct chan_call *call;
1550 pthread_t tid = pthread_self();
1552 if (!pthread_equal(tid, chan_tid))
1553 ast_mutex_lock(&chan_lock);
1554 call = ast->tech_pvt;
1556 CERROR(NULL, ast, "Received hangup from Asterisk, but no call instance exists.\n");
1557 if (!pthread_equal(tid, chan_tid))
1558 ast_mutex_unlock(&chan_lock);
1562 if (!pthread_equal(tid, chan_tid))
1563 CDEBUG(call, ast, "Received hangup from Asterisk thread.\n");
1565 CDEBUG(call, ast, "Received hangup from LCR thread.\n");
1567 /* disconnect asterisk, maybe not required */
1568 ast->tech_pvt = NULL;
1573 CDEBUG(call, ast, "Releasing ref and freeing call instance.\n");
1574 if (ast->hangupcause > 0)
1575 send_release_and_import(call, ast->hangupcause, LOCATION_PRIVATE_LOCAL);
1577 send_release_and_import(call, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL);
1580 if (!pthread_equal(tid, chan_tid))
1581 ast_mutex_unlock(&chan_lock);
1585 /* ref is not set, due to prepare setup or release */
1586 if (call->state == CHAN_LCR_STATE_RELEASE)
1588 /* we get the response to our release */
1589 CDEBUG(call, ast, "Freeing call instance, because we have no ref AND we are requesting no ref.\n");
1593 /* during prepare, we change to release state */
1594 CDEBUG(call, ast, "We must wait until we received our ref, until we can free call instance.\n");
1595 call->state = CHAN_LCR_STATE_RELEASE;
1598 if (!pthread_equal(tid, chan_tid))
1599 ast_mutex_unlock(&chan_lock);
1603 static int lcr_write(struct ast_channel *ast, struct ast_frame *f)
1605 struct chan_call *call;
1608 CDEBUG(NULL, ast, "No subclass\n");
1609 if (!(f->subclass & ast->nativeformats))
1610 CDEBUG(NULL, ast, "Unexpected format.\n");
1612 ast_mutex_lock(&chan_lock);
1613 call = ast->tech_pvt;
1615 ast_mutex_unlock(&chan_lock);
1618 if (call->bchannel && f->samples)
1619 bchannel_transmit(call->bchannel, f->data, f->samples);
1620 ast_mutex_unlock(&chan_lock);
1625 static struct ast_frame *lcr_read(struct ast_channel *ast)
1627 struct chan_call *call;
1631 ast_mutex_lock(&chan_lock);
1632 call = ast->tech_pvt;
1634 ast_mutex_unlock(&chan_lock);
1637 if (call->pipe[0] > -1) {
1638 len = read(call->pipe[0], call->read_buff, sizeof(call->read_buff));
1640 close(call->pipe[0]);
1646 p = call->read_buff;
1647 for (i = 0; i < len; i++) {
1652 call->read_fr.frametype = AST_FRAME_VOICE;
1653 call->read_fr.subclass = ast->nativeformats;
1654 call->read_fr.datalen = len;
1655 call->read_fr.samples = len;
1656 call->read_fr.delivery = ast_tv(0,0);
1657 call->read_fr.data = call->read_buff;
1658 ast_mutex_unlock(&chan_lock);
1660 return &call->read_fr;
1663 static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, size_t datalen)
1665 union parameter newparam;
1667 struct chan_call *call;
1669 ast_mutex_lock(&chan_lock);
1670 call = ast->tech_pvt;
1672 CERROR(NULL, ast, "Received indicate from Asterisk, but no call instance exists.\n");
1673 ast_mutex_unlock(&chan_lock);
1678 case AST_CONTROL_BUSY:
1679 CDEBUG(call, ast, "Received indicate AST_CONTROL_BUSY from Asterisk.\n");
1680 ast_setstate(ast, AST_STATE_BUSY);
1681 if (call->state != CHAN_LCR_STATE_OUT_DISCONNECT) {
1682 /* send message to lcr */
1683 memset(&newparam, 0, sizeof(union parameter));
1684 newparam.disconnectinfo.cause = 17;
1685 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1686 send_message(MESSAGE_DISCONNECT, call->ref, &newparam);
1688 call->state = CHAN_LCR_STATE_OUT_DISCONNECT;
1691 case AST_CONTROL_CONGESTION:
1692 CDEBUG(call, ast, "Received indicate AST_CONTROL_CONGESTION from Asterisk. (cause %d)\n", ast->hangupcause);
1693 if (call->state != CHAN_LCR_STATE_OUT_DISCONNECT) {
1694 /* send message to lcr */
1695 memset(&newparam, 0, sizeof(union parameter));
1696 newparam.disconnectinfo.cause = ast->hangupcause;
1697 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1698 send_message(MESSAGE_DISCONNECT, call->ref, &newparam);
1700 call->state = CHAN_LCR_STATE_OUT_DISCONNECT;
1703 case AST_CONTROL_PROCEEDING:
1704 CDEBUG(call, ast, "Received indicate AST_CONTROL_PROCEEDING from Asterisk.\n");
1705 if (call->state == CHAN_LCR_STATE_IN_SETUP
1706 || call->state == CHAN_LCR_STATE_IN_DIALING) {
1707 /* send message to lcr */
1708 memset(&newparam, 0, sizeof(union parameter));
1709 send_message(MESSAGE_PROCEEDING, call->ref, &newparam);
1711 call->state = CHAN_LCR_STATE_IN_PROCEEDING;
1714 case AST_CONTROL_RINGING:
1715 CDEBUG(call, ast, "Received indicate AST_CONTROL_RINGING from Asterisk.\n");
1716 ast_setstate(ast, AST_STATE_RINGING);
1717 if (call->state == CHAN_LCR_STATE_IN_SETUP
1718 || call->state == CHAN_LCR_STATE_IN_DIALING
1719 || call->state == CHAN_LCR_STATE_IN_PROCEEDING) {
1720 /* send message to lcr */
1721 memset(&newparam, 0, sizeof(union parameter));
1722 send_message(MESSAGE_ALERTING, call->ref, &newparam);
1724 call->state = CHAN_LCR_STATE_IN_ALERTING;
1728 CDEBUG(call, ast, "Received indicate -1.\n");
1732 case AST_CONTROL_VIDUPDATE:
1733 CDEBUG(call, ast, "Received indicate AST_CONTROL_VIDUPDATE.\n");
1736 case AST_CONTROL_HOLD:
1737 CDEBUG(call, ast, "Received indicate AST_CONTROL_HOLD from Asterisk.\n");
1738 /* send message to lcr */
1739 memset(&newparam, 0, sizeof(union parameter));
1740 newparam.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
1741 send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1743 /*start music onhold*/
1744 ast_moh_start(ast,data,ast->musicclass);
1746 case AST_CONTROL_UNHOLD:
1747 CDEBUG(call, ast, "Received indicate AST_CONTROL_UNHOLD from Asterisk.\n");
1748 /* send message to lcr */
1749 memset(&newparam, 0, sizeof(union parameter));
1750 newparam.notifyinfo.notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
1751 send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1758 CERROR(call, ast, "Received indicate from Asterisk with unknown condition %d.\n", cond);
1764 ast_mutex_unlock(&chan_lock);
1771 static int lcr_fixup(struct ast_channel *oldast, struct ast_channel *newast)
1773 struct chan_call *call;
1775 ast_mutex_lock(&chan_lock);
1776 call = oldast->tech_pvt;
1778 CERROR(NULL, oldast, "Received fixup from Asterisk, but no call instance exists.\n");
1779 ast_mutex_unlock(&chan_lock);
1783 CDEBUG(call, oldast, "Received fixup from Asterisk.\n");
1785 ast_mutex_lock(&chan_lock);
1790 * send_text asterisk
1792 static int lcr_send_text(struct ast_channel *ast, const char *text)
1794 struct chan_call *call;
1795 union parameter newparam;
1797 ast_mutex_lock(&chan_lock);
1798 call = ast->tech_pvt;
1800 CERROR(NULL, ast, "Received send_text from Asterisk, but no call instance exists.\n");
1801 ast_mutex_unlock(&chan_lock);
1805 CDEBUG(call, ast, "Received send_text from Asterisk. (text=%s)\n", text);
1806 memset(&newparam, 0, sizeof(union parameter));
1807 strncpy(newparam.notifyinfo.display, text, sizeof(newparam.notifyinfo.display)-1);
1808 send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1809 ast_mutex_lock(&chan_lock);
1816 enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
1817 struct ast_channel *ast2, int flags,
1818 struct ast_frame **fo,
1819 struct ast_channel **rc, int timeoutms)
1822 struct chan_call *call1, *call2;
1823 struct ast_channel *carr[2], *who;
1825 struct ast_frame *f;
1828 CDEBUG(NULL, NULL, "Received briding request from Asterisk.\n");
1833 /* join via dsp (if the channels are currently open) */
1834 ast_mutex_lock(&chan_lock);
1835 bridge_id = new_bridge_id();
1836 call1 = ast1->tech_pvt;
1837 call2 = ast2->tech_pvt;
1840 call1->bridge_id = bridge_id;
1841 if (call1->bchannel)
1842 bchannel_join(call1->bchannel, bridge_id);
1843 call1->bridge_call = call2;
1847 call2->bridge_id = bridge_id;
1848 if (call2->bchannel)
1849 bchannel_join(call2->bchannel, bridge_id);
1850 call2->bridge_call = call1;
1852 ast_mutex_unlock(&chan_lock);
1856 who = ast_waitfor_n(carr, 2, &to);
1859 CDEBUG(NULL, NULL, "Empty read on bridge, breaking out.\n");
1864 if (!f || f->frametype == AST_FRAME_CONTROL) {
1866 CDEBUG(NULL, NULL, "Got hangup.\n");
1868 CDEBUG(NULL, NULL, "Got CONTROL.\n");
1875 if ( f->frametype == AST_FRAME_DTMF ) {
1876 CDEBUG(NULL, NULL, "Got DTMF.\n");
1892 CDEBUG(NULL, NULL, "Releasing bride.\n");
1894 /* split channels */
1895 ast_mutex_lock(&chan_lock);
1896 call1 = ast1->tech_pvt;
1897 call2 = ast2->tech_pvt;
1900 call1->bridge_id = 0;
1901 if (call1->bchannel)
1902 bchannel_join(call1->bchannel, 0);
1903 if (call1->bridge_call)
1904 call1->bridge_call->bridge_call = NULL;
1905 call1->bridge_call = NULL;
1909 call2->bridge_id = 0;
1910 if (call2->bchannel)
1911 bchannel_join(call2->bchannel, 0);
1912 if (call2->bridge_call)
1913 call2->bridge_call->bridge_call = NULL;
1914 call2->bridge_call = NULL;
1916 ast_mutex_unlock(&chan_lock);
1919 return AST_BRIDGE_COMPLETE;
1921 static struct ast_channel_tech lcr_tech = {
1923 .description="Channel driver for connecting to Linux-Call-Router",
1924 .requester=lcr_request,
1925 .send_digit_begin=lcr_digit,
1932 .indicate=lcr_indicate,
1934 .send_text=lcr_send_text,
1943 static int lcr_show_lcr (int fd, int argc, char *argv[])
1948 static int lcr_show_calls (int fd, int argc, char *argv[])
1953 static int lcr_reload_routing (int fd, int argc, char *argv[])
1958 static int lcr_reload_interfaces (int fd, int argc, char *argv[])
1963 static int lcr_port_block (int fd, int argc, char *argv[])
1968 static int lcr_port_unblock (int fd, int argc, char *argv[])
1973 static int lcr_port_unload (int fd, int argc, char *argv[])
1978 static struct ast_cli_entry cli_show_lcr =
1979 { {"lcr", "show", "lcr", NULL},
1981 "Shows current states of LCR core",
1982 "Usage: lcr show lcr\n",
1985 static struct ast_cli_entry cli_show_calls =
1986 { {"lcr", "show", "calls", NULL},
1988 "Shows current calls made by LCR and Asterisk",
1989 "Usage: lcr show calls\n",
1992 static struct ast_cli_entry cli_reload_routing =
1993 { {"lcr", "reload", "routing", NULL},
1995 "Reloads routing conf of LCR, current uncomplete calls will be disconnected",
1996 "Usage: lcr reload routing\n",
1999 static struct ast_cli_entry cli_reload_interfaces =
2000 { {"lcr", "reload", "interfaces", NULL},
2001 lcr_reload_interfaces,
2002 "Reloads interfaces conf of LCR",
2003 "Usage: lcr reload interfaces\n",
2006 static struct ast_cli_entry cli_port_block =
2007 { {"lcr", "port", "block", NULL},
2009 "Blocks LCR port for further calls",
2010 "Usage: lcr port block \"<port>\"\n",
2013 static struct ast_cli_entry cli_port_unblock =
2014 { {"lcr", "port", "unblock", NULL},
2016 "Unblocks or loads LCR port, port is opened my mISDN",
2017 "Usage: lcr port unblock \"<port>\"\n",
2020 static struct ast_cli_entry cli_port_unload =
2021 { {"lcr", "port", "unload", NULL},
2023 "Unloads LCR port, port is closes by mISDN",
2024 "Usage: lcr port unload \"<port>\"\n",
2030 static int lcr_config_exec(struct ast_channel *chan, void *data)
2032 //FIXME: add your aplication code here
2039 * module loading and destruction
2041 int load_module(void)
2045 for (i = 0; i < 256; i++) {
2046 flip_bits[i] = (i>>7) | ((i>>5)&2) | ((i>>3)&4) | ((i>>1)&8)
2047 | (i<<7) | ((i&2)<<5) | ((i&4)<<3) | ((i&8)<<1);
2050 if (read_options() == 0) {
2051 CERROR(NULL, NULL, "%s", options_error);
2052 return AST_MODULE_LOAD_DECLINE;
2055 ast_mutex_init(&chan_lock);
2056 ast_mutex_init(&log_lock);
2058 if (open_socket() < 0) {
2059 /* continue with closed socket */
2062 if (bchannel_initialize()) {
2063 CERROR(NULL, NULL, "Unable to open mISDN device\n");
2065 return AST_MODULE_LOAD_DECLINE;
2069 lcr_tech.capabilities = (options.law=='a')?AST_FORMAT_ALAW:AST_FORMAT_ULAW;
2070 if (ast_channel_register(&lcr_tech)) {
2071 CERROR(NULL, NULL, "Unable to register channel class\n");
2072 bchannel_deinitialize();
2074 return AST_MODULE_LOAD_DECLINE;
2077 ast_register_application("lcr_config", lcr_config_exec, "lcr_config",
2078 "lcr_config(:<opt><optarg>:<opt><optarg>..):\n"
2079 "Sets LCR opts. and optargs\n"
2081 "The available options are:\n"
2082 " d - Send display text on called phone, text is the optparam\n"
2083 " n - don't detect dtmf tones on called channel\n"
2084 " h - make digital outgoing call\n"
2085 " c - make crypted outgoing call, param is keyindex\n"
2086 " e - perform echo cancelation on this channel,\n"
2087 " takes taps as arguments (32,64,128,256)\n"
2088 " s - send Non Inband DTMF as inband\n"
2089 " vr - rxgain control\n"
2090 " vt - txgain control\n"
2095 ast_cli_register(&cli_show_lcr);
2096 ast_cli_register(&cli_show_calls);
2098 ast_cli_register(&cli_reload_routing);
2099 ast_cli_register(&cli_reload_interfaces);
2100 ast_cli_register(&cli_port_block);
2101 ast_cli_register(&cli_port_unblock);
2102 ast_cli_register(&cli_port_unload);
2104 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
2105 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
2106 "Sets mISDN opts. and optargs\n"
2108 "The available options are:\n"
2109 " d - Send display text on called phone, text is the optparam\n"
2110 " n - don't detect dtmf tones on called channel\n"
2111 " h - make digital outgoing call\n"
2112 " c - make crypted outgoing call, param is keyindex\n"
2113 " e - perform echo cancelation on this channel,\n"
2114 " takes taps as arguments (32,64,128,256)\n"
2115 " s - send Non Inband DTMF as inband\n"
2116 " vr - rxgain control\n"
2117 " vt - txgain control\n"
2121 lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
2124 //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
2128 if ((pthread_create(&chan_tid, NULL, chan_thread, NULL)<0))
2130 /* failed to create thread */
2131 bchannel_deinitialize();
2133 ast_channel_unregister(&lcr_tech);
2134 return AST_MODULE_LOAD_DECLINE;
2139 int unload_module(void)
2141 /* First, take us out of the channel loop */
2142 CDEBUG(NULL, NULL, "-- Unregistering mISDN Channel Driver --\n");
2145 pthread_join(chan_tid, NULL);
2147 ast_channel_unregister(&lcr_tech);
2149 ast_unregister_application("lcr_config");
2152 if (mISDN_created) {
2153 bchannel_deinitialize();
2157 if (lcr_sock >= 0) {
2165 int reload_module(void)
2172 #define AST_MODULE "chan_lcr"
2174 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Channel driver for Linux-Call-Router Support (ISDN BRI/PRI)",
2175 .load = load_module,
2176 .unload = unload_module,
2177 .reload = reload_module,