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".
82 u_char flip_bits[256];
84 #warning TODO: bchannel oeffnen und aktivieren (wer macht das?:)
85 #warning reconnect after socket closed, release all calls.
86 #warning debug of call handling
87 #warning ausloesen beim socket-verlust
94 #include <sys/types.h>
98 #include <sys/ioctl.h>
99 #include <sys/socket.h>
102 #include <semaphore.h>
104 #include <asterisk/module.h>
105 #include <asterisk/channel.h>
106 #include <asterisk/config.h>
107 #include <asterisk/logger.h>
108 #include <asterisk/pbx.h>
109 #include <asterisk/options.h>
110 #include <asterisk/io.h>
111 #include <asterisk/frame.h>
112 #include <asterisk/translate.h>
113 #include <asterisk/cli.h>
114 #include <asterisk/musiconhold.h>
115 #include <asterisk/dsp.h>
116 #include <asterisk/translate.h>
117 #include <asterisk/file.h>
118 #include <asterisk/callerid.h>
119 #include <asterisk/indications.h>
120 #include <asterisk/app.h>
121 #include <asterisk/features.h>
122 #include <asterisk/sched.h>
124 #include "extension.h"
126 #include "lcrsocket.h"
128 #include "bchannel.h"
129 #include "chan_lcr.h"
130 #include "callerid.h"
132 CHAN_LCR_STATE // state description structure
137 char lcr_type[]="lcr";
140 ast_mutex_t chan_lock;
143 int glob_channel = 0;
148 struct admin_list *next;
149 struct admin_msg msg;
150 } *admin_first = NULL;
152 static struct ast_channel_tech lcr_tech;
155 * channel and call instances
157 struct chan_call *call_first;
159 struct chan_call *find_call_ref(unsigned long ref)
161 struct chan_call *call = call_first;
165 if (call->ref == ref)
173 struct chan_call *find_call_ast(struct ast_channel *ast)
175 struct chan_call *call = call_first;
179 if (call->ast == ast)
186 struct chan_call *find_call_handle(unsigned long handle)
188 struct chan_call *call = call_first;
192 if (call->bchannel_handle == handle)
200 struct chan_call *alloc_call(void)
202 struct chan_call **callp = &call_first;
205 callp = &((*callp)->next);
207 *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
209 memset(*callp, 0, sizeof(struct chan_call));
210 if (pipe((*callp)->pipe) < 0) {
218 void free_call(struct chan_call *call)
220 struct chan_call **temp = &call_first;
226 *temp = (*temp)->next;
228 close(call->pipe[0]);
230 close(call->pipe[1]);
233 if (call->bchannel->call)
234 call->bchannel->call = NULL;
238 if (call->bridge_call)
240 if (call->bridge_call->bridge_call)
241 call->bridge_call->bridge_call = NULL;
248 temp = &((*temp)->next);
252 unsigned short new_bridge_id(void)
254 struct chan_call *call;
255 unsigned short id = 1;
257 /* search for lowest bridge id that is not in use and not 0 */
263 if (call->bridge_id == id)
276 * receive bchannel data
278 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
282 void rx_dtmf(struct bchannel *bchannel, char tone)
287 * enque message to LCR
289 int send_message(int message_type, unsigned long ref, union parameter *param)
291 struct admin_list *admin, **adminp;
293 adminp = &admin_first;
295 adminp = &((*adminp)->next);
296 admin = (struct admin_list *)malloc(sizeof(struct admin_list));
299 admin->msg.type = message_type;
300 admin->msg.ref = ref;
301 memcpy(&admin->msg.param, param, sizeof(union parameter));
307 * send setup info to LCR
308 * this function is called, when asterisk call is received and ref is received
310 static void send_setup_to_lcr(struct chan_call *call)
312 union parameter newparam;
313 struct ast_channel *ast = call->ast;
315 if (!call->ast || !call->ref)
318 /* send setup message to LCR */
319 memset(&newparam, 0, sizeof(union parameter));
320 newparam.setup.callerinfo.itype = INFO_ITYPE_CHAN;
321 newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
322 if (ast->cid.cid_num) if (ast->cid.cid_num[0])
323 strncpy(newparam.setup.callerinfo.id, ast->cid.cid_num, sizeof(newparam.setup.callerinfo.id)-1);
324 if (ast->cid.cid_name) if (ast->cid.cid_name[0])
325 strncpy(newparam.setup.callerinfo.name, ast->cid.cid_name, sizeof(newparam.setup.callerinfo.name)-1);
326 if (ast->cid.cid_rdnis) if (ast->cid.cid_rdnis[0])
328 strncpy(newparam.setup.redirinfo.id, ast->cid.cid_rdnis, sizeof(newparam.setup.redirinfo.id)-1);
329 newparam.setup.redirinfo.itype = INFO_ITYPE_CHAN;
330 newparam.setup.redirinfo.ntype = INFO_NTYPE_UNKNOWN;
332 switch(ast->cid.cid_pres & AST_PRES_RESTRICTION)
334 case AST_PRES_ALLOWED:
335 newparam.setup.callerinfo.present = INFO_PRESENT_ALLOWED;
337 case AST_PRES_RESTRICTED:
338 newparam.setup.callerinfo.present = INFO_PRESENT_RESTRICTED;
340 case AST_PRES_UNAVAILABLE:
341 newparam.setup.callerinfo.present = INFO_PRESENT_NOTAVAIL;
344 newparam.setup.callerinfo.present = INFO_PRESENT_NULL;
346 switch(ast->cid.cid_ton)
349 newparam.setup.callerinfo.ntype = INFO_NTYPE_SUBSCRIBER;
352 newparam.setup.callerinfo.ntype = INFO_NTYPE_NATIONAL;
355 newparam.setup.callerinfo.ntype = INFO_NTYPE_INTERNATIONAL;
358 newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
360 newparam.setup.capainfo.bearer_capa = ast->transfercapability;
362 // newparam.setup.capainfo.bearer_user = alaw 3, ulaw 2;
363 newparam.setup.capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
364 newparam.setup.capainfo.hlc = INFO_HLC_NONE;
365 newparam.setup.capainfo.exthlc = INFO_HLC_NONE;
366 send_message(MESSAGE_SETUP, call->ref, &newparam);
368 /* change to outgoing setup state */
369 call->state = CHAN_LCR_STATE_OUT_SETUP;
373 * send dialing info to LCR
374 * this function is called, when setup acknowledge is received and dialing
377 static void send_dialque_to_lcr(struct chan_call *call)
379 union parameter newparam;
381 if (!call->ast || !call->ref || !call->dialque)
384 /* send setup message to LCR */
385 memset(&newparam, 0, sizeof(union parameter));
386 strncpy(newparam.information.id, call->dialque, sizeof(newparam.information.id)-1);
387 call->dialque[0] = '\0';
388 send_message(MESSAGE_INFORMATION, call->ref, &newparam);
392 * in case of a bridge, the unsupported message can be forwarded directly
393 * to the remote call.
395 static void bridge_message_if_bridged(struct chan_call *call, int message_type, union parameter *param)
399 if (!call->bridge_call) return;
400 send_message(message_type, call->bridge_call->ref, param);
404 * check if extension matches and start asterisk
405 * if it can match, proceed
408 static void lcr_setup_pbx(struct chan_call *call, struct ast_channel *ast, int complete)
415 if (!ast_canmatch_extension(ast, ast->context, call->dad, 1, call->oad))
419 if (!ast_exists_extension(ast, ast->context, call->dad, 1, call->oad))
424 /* send setup acknowledge to lcr */
425 memset(&newparam, 0, sizeof(union parameter));
426 send_message(MESSAGE_PROCEEDING, call->ref, &newparam);
429 call->state = CHAN_LCR_STATE_IN_PROCEEDING;
434 if (ast_canmatch_extension(ast, ast->context, dad, 1, oad))
436 /* send setup acknowledge to lcr */
437 memset(&newparam, 0, sizeof(union parameter));
438 send_message(MESSAGE_OVERLAP, call->ref, &newparam);
441 call->state = CHAN_LCR_STATE_IN_DIALING;
443 /* if match, start pbx */
444 if (ast_exists_extension(ast, ast->context, dad, 1, oad))
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);
460 /* release asterisk */
461 ast->hangupcause = call->cause;
462 ast_queue_hangup(ast);
463 /* change to release state */
464 call->state = CHAN_LCR_STATE_RELEASE;
468 /* send setup to asterisk */
469 ret = ast_pbx_start(ast);
472 cause = (ret==-2)?34:27;
475 call->pbx_started = 1;
480 * incoming setup from LCR
482 static void lcr_in_setup(struct chan_call *call, int message_type, union parameter *param)
484 struct ast_channel *ast;
485 union parameter newparam;
487 /* create asterisk channel instrance */
488 ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
492 memset(&newparam, 0, sizeof(union parameter));
493 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
494 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
495 send_message(MESSAGE_RELEASE, call->ref, &newparam);
500 /* set ast pointer */
502 ast->tech_pvt = call;
503 ast->tech = &lcr_tech;
504 ast->fds[0] = call->pipe[0];
506 /* fill setup information */
507 if (param->setup.dialinginfo.id)
508 strncpy(ast->exten, param->setup.dialinginfo.id, AST_MAX_EXTENSION-1);
509 if (param->setup.context[0])
510 strncpy(ast->context, param->setup.exten, AST_MAX_CONTEXT-1);
511 if (param->setup.callerinfo.id[0])
512 ast->cid.cid_num = strdup(param->setup.callerinfo.id);
513 if (param->setup.callerinfo.name[0])
514 ast->cid.cid_name = strdup(param->setup.callerinfo.name);
517 if (param->setup.redirinfo.id[0])
518 ast->cid.cid_name = strdup(numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, configfile->prefix_nat, configfile->prefix_inter));
520 switch (param->setup.callerinfo.present)
522 case INFO_PRESENT_ALLOWED:
523 ast->cid.cid_pres = AST_PRES_ALLOWED;
525 case INFO_PRESENT_RESTRICTED:
526 ast->cid.cid_pres = AST_PRES_RESTRICTED;
529 ast->cid.cid_pres = AST_PRES_UNAVAILABLE;
531 switch (param->setup.callerinfo.ntype)
533 case INFO_NTYPE_SUBSCRIBER:
534 ast->cid.cid_ton = 4;
536 case INFO_NTYPE_NATIONAL:
537 ast->cid.cid_ton = 2;
539 case INFO_NTYPE_INTERNATIONAL:
540 ast->cid.cid_ton = 1;
543 ast->cid.cid_ton = 0;
545 ast->transfercapability = param->setup.capainfo.bearer_capa;
546 strcpy(call->dad, param->setup.dialinginfo.id);
547 strcpy(call->oad, numberrize_callerinfo(param->setup.callerinfo.id, param->setup.callerinfo.ntype, configfile->prefix_nat, configfile->prefix_inter));
549 /* configure channel */
552 ast->nativeformat = configfile->lawformat;
553 ast->readformat = ast->rawreadformat = configfile->lawformat;
554 ast->writeformat = ast->rawwriteformat = configfile->lawformat;
556 ast->hangupcause = 0;
559 call->state = CHAN_LCR_STATE_IN_SETUP;
561 lcr_start_pbx(call, ast, param->setup.dialinginfo.complete);
565 * incoming setup acknowledge from LCR
567 static void lcr_in_overlap(struct chan_call *call, int message_type, union parameter *param)
569 if (!call->ast) return;
571 /* send pending digits in dialque */
573 send_dialque_to_lcr(call);
574 /* change to overlap state */
575 call->state = CHAN_LCR_STATE_OUT_DIALING;
579 * incoming proceeding from LCR
581 static void lcr_in_proceeding(struct chan_call *call, int message_type, union parameter *param)
584 call->state = CHAN_LCR_STATE_OUT_PROCEEDING;
585 /* send event to asterisk */
587 ast_queue_control(call->ast, AST_CONTROL_PROCEEDING);
591 * incoming alerting from LCR
593 static void lcr_in_alerting(struct chan_call *call, int message_type, union parameter *param)
596 call->state = CHAN_LCR_STATE_OUT_ALERTING;
597 /* send event to asterisk */
599 ast_queue_control(call->ast, AST_CONTROL_RINGING);
603 * incoming connect from LCR
605 static void lcr_in_connect(struct chan_call *call, int message_type, union parameter *param)
608 call->state = CHAN_LCR_STATE_CONNECT;
609 /* copy connectinfo */
610 memcpy(&call->connectinfo, ¶m->connectinfo, sizeof(struct connect_info));
611 /* send event to asterisk */
613 ast_queue_control(call->ast, AST_CONTROL_ANSWER);
617 * incoming disconnect from LCR
619 static void lcr_in_disconnect(struct chan_call *call, int message_type, union parameter *param)
621 struct ast_channel *ast = call->ast;
622 union parameter newparam;
625 call->state = CHAN_LCR_STATE_IN_DISCONNECT;
627 call->cause = param->disconnectinfo.cause;
628 call->location = param->disconnectinfo.location;
631 wenn setup raus geht, pointer
632 /* if bridge, forward disconnect and return */
633 if (call->bridge_call)
635 bridge_message_if_bridged(call, message_type, param);
639 newparam.disconnectinfo.cause = CAUSE_NORMAL;
640 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
641 send_message(MESSAGE_RELEASE, call->ref, &newparam);
643 /* release asterisk */
644 ast->hangupcause = call->cause;
645 ast_queue_hangup(ast);
646 /* change to release state */
647 call->state = CHAN_LCR_STATE_RELEASE;
651 * incoming setup acknowledge from LCR
653 static void lcr_in_release(struct chan_call *call, int message_type, union parameter *param)
655 struct ast_channel *ast = call->ast;
659 /* change to release state */
660 call->state = CHAN_LCR_STATE_RELEASE;
661 /* copy release info */
664 call->cause = param->disconnectinfo.cause;
665 call->location = param->disconnectinfo.location;
667 /* if we have an asterisk instance, send hangup, else we are done */
670 ast->hangupcause = call->cause;
671 ast_queue_hangup(ast);
680 * incoming information from LCR
682 static void lcr_in_information(struct chan_call *call, int message_type, union parameter *param)
687 if (!call->ast) return;
689 /* pbx not started */
690 if (!call->pbx_started)
692 strncat(ast->exten, param->information.id, AST_MAX_EXTENSION-1);
693 lcr_start_pbx(call, ast, param->information.complete);
698 p = param->information.id;
699 if (call->state == CHAN_LCR_STATE_IN_DIALING && *p)
703 /* send digit to asterisk */
704 memset(&fr, 0, sizeof(fr));
705 fr.frametype = AST_FRAME_DTMF;
707 fr.delivery = ast_tv(0, 0);
708 ast_queue_frame(call->ast, &fr);
712 /* use bridge to forware message not supported by asterisk */
713 if (call->state == CHAN_LCR_STATE_CONNECT)
714 bridge_message_if_bridged(call, message_type, param);
718 * incoming information from LCR
720 static void lcr_in_notify(struct chan_call *call, int message_type, union parameter *param)
722 if (!call->ast) return;
724 /* use bridge to forware message not supported by asterisk */
725 bridge_message_if_bridged(call, message_type, param);
729 * incoming information from LCR
731 static void lcr_in_facility(struct chan_call *call, int message_type, union parameter *param)
733 if (!call->ast) return;
735 /* use bridge to forware message not supported by asterisk */
736 bridge_message_if_bridged(call, message_type, param);
740 * message received from LCR
742 int receive_message(int message_type, unsigned long ref, union parameter *param)
744 union parameter newparam;
745 struct bchannel *bchannel;
746 struct chan_call *call;
748 memset(&newparam, 0, sizeof(union parameter));
750 /* handle bchannel message*/
751 if (message_type == MESSAGE_BCHANNEL)
753 switch(param->bchannel.type)
755 case BCHANNEL_ASSIGN:
756 if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
758 fprintf(stderr, "error: bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
761 /* create bchannel */
762 bchannel = alloc_bchannel(param->bchannel.handle);
765 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
769 /* configure channel */
770 bchannel->b_tx_gain = param->bchannel.tx_gain;
771 bchannel->b_rx_gain = param->bchannel.rx_gain;
772 strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
773 if (param->bchannel.crypt_len)
775 bchannel->b_crypt_len = param->bchannel.crypt_len;
776 bchannel->b_crypt_type = param->bchannel.crypt_type;
777 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
779 bchannel->b_txdata = 0;
780 bchannel->b_dtmf = 1;
781 bchannel->b_tx_dejitter = 1;
783 /* in case, ref is not set, this bchannel instance must
784 * be created until it is removed again by LCR */
786 if ((call = find_call_ref(ref)))
788 bchannel->call = call;
789 call->bchannel = bchannel;
790 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
792 bchannel_join(bchannel, call->bridge_id);
794 if (bchannel_create(bchannel))
795 bchannel_activate(bchannel, 1);
798 newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
799 newparam.bchannel.handle = param->bchannel.handle;
800 send_message(MESSAGE_BCHANNEL, 0, &newparam);
803 case BCHANNEL_REMOVE:
804 if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
806 #warning alle fprintf nach ast_log
807 fprintf(stderr, "error: bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
810 /* unklink from call and destroy bchannel */
811 free_bchannel(bchannel);
814 newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
815 newparam.bchannel.handle = param->bchannel.handle;
816 send_message(MESSAGE_BCHANNEL, 0, &newparam);
821 fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
827 if (message_type == MESSAGE_NEWREF)
829 if (param->direction)
831 /* new ref from lcr */
832 if (!ref || find_call_ref(ref))
834 fprintf(stderr, "illegal new ref %ld received\n", ref);
837 /* allocate new call instance */
840 call->state = CHAN_LCR_STATE_IN_PREPARE;
843 /* wait for setup (or release from asterisk) */
846 /* new ref, as requested from this remote application */
847 call = find_call_ref(0);
850 /* send release, if ref does not exist */
851 newparam.disconnectinfo.cause = CAUSE_NORMAL;
852 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
853 send_message(MESSAGE_RELEASE, ref, &newparam);
858 /* send pending setup info */
859 if (call->state == CHAN_LCR_STATE_OUT_PREPARE)
860 send_setup_to_lcr(call);
861 /* release if asterisk has signed off */
862 else if (call->state == CHAN_LCR_STATE_RELEASE)
867 newparam.disconnectinfo.cause = call->cause;
868 newparam.disconnectinfo.location = call->location;
871 newparam.disconnectinfo.cause = 16;
872 newparam.disconnectinfo.location = 5;
874 send_message(MESSAGE_RELEASE, ref, &newparam);
886 fprintf(stderr, "received message %d without ref\n", message_type);
889 call = find_call_ref(ref);
892 /* ignore ref that is not used (anymore) */
896 /* handle messages */
900 lcr_in_setup(call, message_type, param);
903 case MESSAGE_OVERLAP:
904 lcr_in_overlap(call, message_type, param);
907 case MESSAGE_PROCEEDING:
908 lcr_in_proceeding(call, message_type, param);
911 case MESSAGE_ALERTING:
912 lcr_in_alerting(call, message_type, param);
915 case MESSAGE_CONNECT:
916 lcr_in_connect(call, message_type, param);
919 case MESSAGE_DISCONNECT:
920 lcr_in_disconnect(call, message_type, param);
923 case MESSAGE_RELEASE:
924 lcr_in_release(call, message_type, param);
927 case MESSAGE_INFORMATION:
928 lcr_in_information(call, message_type, param);
932 lcr_in_notify(call, message_type, param);
935 case MESSAGE_FACILITY:
936 lcr_in_facility(call, message_type, param);
939 case MESSAGE_PATTERN:
943 case MESSAGE_NOPATTERN:
947 case MESSAGE_AUDIOPATH:
960 * warning! not thread safe
961 * returns -1 for socket error, 0 for no work, 1 for work
963 int handle_socket(void)
967 struct admin_message msg;
968 struct admin_list *admin;
972 #warning SOCKET FEHLT!
973 /* read from socket */
974 len = read(sock, &msg, sizeof(msg));
977 printf("Socket closed\n");
978 return(-1); // socket closed
982 if (len != sizeof(msg))
984 fprintf(stderr, "Socket short read (%d)\n", len);
985 return(-1); // socket error
987 if (msg.message != ADMIN_MESSAGE)
989 fprintf(stderr, "Socket received illegal message %d\n", msg.message);
990 return(-1); // socket error
992 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
993 printf("message received %d\n", msg.u.msg.type);
997 if (errno != EWOULDBLOCK)
999 fprintf(stderr, "Socket error %d\n", errno);
1004 /* write to socket */
1007 admin = admin_first;
1008 len = write(sock, &admin->msg, sizeof(msg));
1011 printf("Socket closed\n");
1012 return(-1); // socket closed
1016 if (len != sizeof(msg))
1018 fprintf(stderr, "Socket short write (%d)\n", len);
1019 return(-1); // socket error
1022 admin_first = admin->next;
1028 if (errno != EWOULDBLOCK)
1030 fprintf(stderr, "Socket error %d\n", errno);
1039 * open and close socket and thread
1041 int open_socket(void)
1045 char *socket_name = SOCKET_NAME;
1047 struct sockaddr_un sock_address;
1048 unsigned long on = 1;
1049 union parameter param;
1052 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
1054 ast_log(LOG_ERROR, "Failed to create socket.\n");
1058 /* set socket address and name */
1059 memset(&sock_address, 0, sizeof(sock_address));
1060 sock_address.sun_family = PF_UNIX;
1061 strcpy(sock_address.sun_path, socket_name);
1063 /* connect socket */
1064 if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
1067 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
1071 /* set non-blocking io */
1072 if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
1075 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
1079 /* enque hello message */
1080 memset(¶m, 0, sizeof(param));
1081 strcpy(param.hello.application, "asterisk");
1082 send_message(MESSAGE_HELLO, 0, ¶m);
1087 void close_socket(int sock)
1094 static void *chan_thread(void *arg)
1099 ast_mutex_lock(&chan_lock);
1106 ret = handle_socket();
1113 ret = bchannel_handle();
1119 ast_mutex_unlock(&chan_lock);
1121 ast_mutex_lock(&chan_lock);
1125 ast_mutex_unlock(&chan_lock);
1131 * new asterisk instance
1133 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
1135 union parameter newparam;
1136 struct ast_channel *ast;
1137 struct chan_call *call;
1139 ast_mutex_lock(&chan_lock);
1141 /* create call instance */
1142 call = alloc_call();
1145 /* failed to create instance */
1148 /* create asterisk channel instrance */
1149 ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
1153 /* failed to create instance */
1157 ast->tech_pvt = call;
1159 ast->tech = &lcr_tech;
1160 /* configure channel */
1161 snprintf(ast->name, sizeof(ast->name), "%s/%d", lcr_type, ++glob_channel);
1162 ast->name[sizeof(ast->name)-1] = '\0';
1165 ast->nativeformat = configfile->lawformat;
1166 ast->readformat = ast->rawreadformat = configfile->lawformat;
1167 ast->writeformat = ast->rawwriteformat = configfile->lawformat;
1169 ast->hangupcause = 0;
1170 /* send MESSAGE_NEWREF */
1171 memset(&newparam, 0, sizeof(union parameter));
1172 newparam.direction = 0; /* request from app */
1173 send_message(MESSAGE_NEWREF, 0, &newparam);
1175 call->state = CHAN_LCR_STATE_OUT_PREPARE;
1177 ast_mutex_unlock(&chan_lock);
1183 * call from asterisk
1185 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
1187 struct chan_call *call;
1189 ast_mutex_lock(&chan_lock);
1190 call = ast->tech_pvt;
1192 ast_mutex_unlock(&chan_lock);
1197 #warning hier muss noch
1199 ast_copy_string(buf, dest, sizeof(buf)-1);
1201 port_str=strsep(&p, "/");
1202 dad=strsep(&p, "/");
1205 /* send setup message, if we already have a callref */
1207 send_setup_to_lcr(call);
1210 // ast_verbose("Call: ext:%s dest:(%s) -> dad(%s) \n", ast->exten,dest, dad);
1212 ast_mutex_unlock(&chan_lock);
1216 static int lcr_digit(struct ast_channel *ast, char digit)
1218 struct chan_call *call;
1219 union parameter newparam;
1222 /* only pass IA5 number space */
1223 if (digit > 126 || digit < 32)
1226 ast_mutex_lock(&chan_lock);
1227 call = ast->tech_pvt;
1229 ast_mutex_unlock(&chan_lock);
1233 /* send information or queue them */
1234 if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING)
1236 memset(&newparam, 0, sizeof(union parameter));
1237 newparam.information.id[0] = digit;
1238 newparam.information.id[1] = '\0';
1239 send_message(MESSAGE_INFORMATION, call->ref, &newparam);
1242 && (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP));
1245 strncat(call->dialque, buf, strlen(call->dialque)-1);
1248 ast_mutex_unlock(&chan_lock);
1253 static int lcr_answer(struct ast_channel *ast)
1255 union parameter newparam;
1256 struct chan_call *call;
1258 ast_mutex_lock(&chan_lock);
1259 call = ast->tech_pvt;
1261 ast_mutex_unlock(&chan_lock);
1265 /* copy connectinfo, if bridged */
1266 if (call->bridge_call)
1267 memcpy(&call->connectinfo, &call->bridge_call->connectinfo, sizeof(struct connect_info));
1268 /* send connect message to lcr */
1269 memset(&newparam, 0, sizeof(union parameter));
1270 memcpy(&newparam.connectinfo, &call->connectinfo, sizeof(struct connect_info));
1271 send_message(MESSAGE_CONNECT, call->ref, &newparam);
1273 call->state = CHAN_LCR_STATE_CONNECT;
1275 ast_mutex_unlock(&chan_lock);
1279 static int lcr_hangup(struct ast_channel *ast)
1281 union parameter newparam;
1282 struct chan_call *call;
1284 ast_mutex_lock(&chan_lock);
1285 call = ast->tech_pvt;
1287 ast_mutex_unlock(&chan_lock);
1291 /* disconnect asterisk, maybe not required */
1292 ast->tech_pvt = NULL;
1297 memset(&newparam, 0, sizeof(union parameter));
1298 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
1299 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1300 send_message(MESSAGE_RELEASE, call->ref, &newparam);
1303 ast_mutex_unlock(&chan_lock);
1307 /* ref is not set, due to prepare setup or release */
1308 if (call->state == CHAN_LCR_STATE_RELEASE)
1310 /* we get the response to our release */
1314 /* during prepare, we change to release state */
1315 call->state = CHAN_LCR_STATE_RELEASE;
1318 ast_mutex_unlock(&chan_lock);
1322 static int lcr_write(struct ast_channel *ast, struct ast_frame *f)
1324 struct chan_call *call;
1325 unsigned char *buffer[1024], *s, *d = buffer;
1327 ast_mutex_lock(&chan_lock);
1328 call = ast->tech_pvt;
1330 ast_mutex_unlock(&chan_lock);
1333 if (call->bchannel && ((ii = f->samples)))
1335 if (ii > sizeof(buffer))
1338 for (i = 0, i < ii, i++)
1339 *d++ = flip_bits[*s++];
1340 bchannel_transmit(call->bchannel, buffer, ii);
1342 ast_mutex_unlock(&chan_lock);
1347 static struct ast_frame *lcr_read(struct ast_channel *ast)
1349 struct chan_call *call;
1353 ast_mutex_lock(&chan_lock);
1354 call = ast->tech_pvt;
1356 ast_mutex_unlock(&chan_lock);
1359 len = read(call->pipe[0], call->read_buf, sizeof(call->read_buf));
1364 for (i = 0, i < len, i++) {
1369 call->read_fr.frametype = AST_FRAME_SPEECH;
1371 call->read_fr.subtype = AST_FORMAT_ALAW;
1372 call->read_fr.datalen = len;
1373 call->read_fr.samples = len;
1374 call->read_fr.delivery = ast_tv(0,0);
1375 call->read_fr.data = call->read_buf;
1376 ast_mutex_unlock(&chan_lock);
1378 return &call->read_fr;
1381 static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, size_t datalen)
1383 union parameter newparam;
1385 struct chan_call *call;
1387 ast_mutex_lock(&chan_lock);
1388 call = ast->tech_pvt;
1390 ast_mutex_unlock(&chan_lock);
1395 case AST_CONTROL_BUSY:
1396 /* send message to lcr */
1397 memset(&newparam, 0, sizeof(union parameter));
1398 newparam.disconnectinfo.cause = 17;
1399 newparam.disconnectinfo.location = 5;
1400 send_message(MESSAGE_DISCONNECT, call->ref, &newparam);
1402 call->state = CHAN_LCR_STATE_OUT_DISCONNECT;
1404 ast_mutex_unlock(&chan_lock);
1406 case AST_CONTROL_CONGESTION:
1408 ast_mutex_unlock(&chan_lock);
1410 case AST_CONTROL_RINGING:
1411 /* send message to lcr */
1412 memset(&newparam, 0, sizeof(union parameter));
1413 send_message(MESSAGE_ALERTING, call->ref, &newparam);
1415 call->state = CHAN_LCR_STATE_OUT_ALERTING;
1417 ast_mutex_unlock(&chan_lock);
1421 ast_mutex_unlock(&chan_lock);
1424 case AST_CONTROL_VIDUPDATE:
1427 case AST_CONTROL_HOLD:
1428 /* send message to lcr */
1429 memset(&newparam, 0, sizeof(union parameter));
1430 newparam.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
1431 send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1433 case AST_CONTROL_UNHOLD:
1434 /* send message to lcr */
1435 memset(&newparam, 0, sizeof(union parameter));
1436 newparam.notifyinfo.notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
1437 send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1441 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, ast->name);
1443 ast_mutex_unlock(&chan_lock);
1448 ast_mutex_unlock(&chan_lock);
1455 enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
1456 struct ast_channel *ast2, int flags,
1457 struct ast_frame **fo,
1458 struct ast_channel **rc, int timeoutms)
1461 struct chan_call *call1, *call2;
1462 struct ast_channel *carr[2], *who;
1464 struct ast_frame *f;
1467 /* join via dsp (if the channels are currently open) */
1468 ast_mutex_lock(&chan_lock);
1469 bridge_id = new_bridge_id();
1470 call1 = ast1->tech_pvt;
1471 call2 = ast2->tech_pvt;
1474 call1->bridge_id = bridge_id;
1475 if (call1->bchannel)
1476 bchannel_join(call1->bchannel, bridge_id);
1477 call1->bridge_call = call2;
1481 call2->bridge_id = bridge_id;
1482 if (call2->bchannel)
1483 bchannel_join(call2->bchannel, bridge_id);
1484 call2->bridge_call = call1;
1486 ast_mutex_unlock(&chan_lock);
1489 who = ast_waitfor_n(carr, 2, &to);
1492 ast_log(LOG_NOTICE,"misdn_bridge: empty read, breaking out\n");
1497 if (!f || f->frametype == AST_FRAME_CONTROL) {
1504 if ( f->frametype == AST_FRAME_DTMF ) {
1510 #warning kann einfach gesendet werden. dsp slittet automatisch, wenn frames kommen, bis der fifo leer ist.
1512 if (f->frametype == AST_FRAME_VOICE) {
1527 /* split channels */
1528 ast_mutex_lock(&chan_lock);
1529 call1 = ast1->tech_pvt;
1530 call2 = ast2->tech_pvt;
1533 call1->bridge_id = 0;
1534 if (call1->bchannel)
1535 bchannel_join(call1->bchannel, 0);
1536 if (call1->bridge_call)
1537 call1->bridge_call->bridge_call = NULL;
1538 call1->bridge_call = NULL;
1542 call2->bridge_id = 0;
1543 if (call2->bchannel)
1544 bchannel_join(call2->bchannel, 0);
1545 if (call2->bridge_call)
1546 call2->bridge_call->bridge_call = NULL;
1547 call2->bridge_call = NULL;
1549 ast_mutex_unlock(&chan_lock);
1552 return AST_BRIDGE_COMPLETE;
1554 static struct ast_channel_tech lcr_tech = {
1556 .description="Channel driver for connecting to Linux-Call-Router",
1558 .capabilities=AST_FORMAT_ALAW,
1559 .requester=lcr_request,
1560 .send_digit_begin=lcr_digit,
1567 .indicate=lcr_indicate,
1568 // .fixup=lcr_fixup,
1569 // .send_text=lcr_send_text,
1577 static int lcr_show_lcr (int fd, int argc, char *argv[])
1582 static int lcr_show_calls (int fd, int argc, char *argv[])
1587 static int lcr_reload_routing (int fd, int argc, char *argv[])
1592 static int lcr_reload_interfaces (int fd, int argc, char *argv[])
1597 static int lcr_port_block (int fd, int argc, char *argv[])
1602 static int lcr_port_unblock (int fd, int argc, char *argv[])
1607 static int lcr_port_unload (int fd, int argc, char *argv[])
1612 static struct ast_cli_entry cli_show_lcr =
1613 { {"lcr", "show", "lcr", NULL},
1615 "Shows current states of LCR core",
1616 "Usage: lcr show lcr\n",
1619 static struct ast_cli_entry cli_show_calls =
1620 { {"lcr", "show", "calls", NULL},
1622 "Shows current calls made by LCR and Asterisk",
1623 "Usage: lcr show calls\n",
1626 static struct ast_cli_entry cli_reload_routing =
1627 { {"lcr", "reload", "routing", NULL},
1629 "Reloads routing conf of LCR, current uncomplete calls will be disconnected",
1630 "Usage: lcr reload routing\n",
1633 static struct ast_cli_entry cli_reload_interfaces =
1634 { {"lcr", "reload", "interfaces", NULL},
1635 lcr_reload_interfaces,
1636 "Reloads interfaces conf of LCR",
1637 "Usage: lcr reload interfaces\n",
1640 static struct ast_cli_entry cli_port_block =
1641 { {"lcr", "port", "block", NULL},
1643 "Blocks LCR port for further calls",
1644 "Usage: lcr port block \"<port>\"\n",
1647 static struct ast_cli_entry cli_port_unblock =
1648 { {"lcr", "port", "unblock", NULL},
1650 "Unblocks or loads LCR port, port is opened my mISDN",
1651 "Usage: lcr port unblock \"<port>\"\n",
1654 static struct ast_cli_entry cli_port_unload =
1655 { {"lcr", "port", "unload", NULL},
1657 "Unloads LCR port, port is closes by mISDN",
1658 "Usage: lcr port unload \"<port>\"\n",
1663 * module loading and destruction
1665 int load_module(void)
1669 for (i = 0, i < 256, i++)
1670 flip_bits[i] = (i>>7) | ((i>>5)&2) | ((i>>3)&4) | ((i>>1)&8)
1671 || = (i<<7) | ((i&2)<<5) | ((i&4)<<3) | ((i&8)<<1);
1673 ast_mutex_init(&chan_lock);
1675 if (!(lcr_sock = open_socket())) {
1676 ast_log(LOG_ERROR, "Unable to connect\n");
1678 /* continue with closed socket */
1681 if (!bchannel_initialize()) {
1682 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
1683 close_socket(lcr_sock);
1688 if (ast_channel_register(&lcr_tech)) {
1689 ast_log(LOG_ERROR, "Unable to register channel class\n");
1690 bchannel_deinitialize();
1691 close_socket(lcr_sock);
1696 ast_cli_register(&cli_show_lcr);
1697 ast_cli_register(&cli_show_calls);
1699 ast_cli_register(&cli_reload_routing);
1700 ast_cli_register(&cli_reload_interfaces);
1701 ast_cli_register(&cli_port_block);
1702 ast_cli_register(&cli_port_unblock);
1703 ast_cli_register(&cli_port_unload);
1705 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
1706 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
1707 "Sets mISDN opts. and optargs\n"
1709 "The available options are:\n"
1710 " d - Send display text on called phone, text is the optparam\n"
1711 " n - don't detect dtmf tones on called channel\n"
1712 " h - make digital outgoing call\n"
1713 " c - make crypted outgoing call, param is keyindex\n"
1714 " e - perform echo cancelation on this channel,\n"
1715 " takes taps as arguments (32,64,128,256)\n"
1716 " s - send Non Inband DTMF as inband\n"
1717 " vr - rxgain control\n"
1718 " vt - txgain control\n"
1722 lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1724 chan_lcr_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
1726 //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1730 if ((pthread_create(&chan_tid, NULL, chan_thread, NULL)<0))
1732 /* failed to create thread */
1733 bchannel_deinitialize();
1734 close_socket(lcr_sock);
1735 ast_channel_unregister(&lcr_tech);
1741 int unload_module(void)
1743 /* First, take us out of the channel loop */
1744 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
1747 pthread_join(chan_tid, NULL);
1749 ast_channel_unregister(&lcr_tech);
1751 if (mISDN_created) {
1752 bchannel_deinitialize();
1756 if (lcr_sock >= 0) {
1764 static int reload_module(void)
1771 ast_mutex_t usecnt_lock;
1777 ast_mutex_lock(&usecnt_lock);
1779 ast_mutex_unlock(&usecnt_lock);
1784 char *desc="Channel driver for lcr";
1786 char *description(void)
1793 return ASTERISK_GPL_KEY;
1796 #define AST_MODULE "chan_lcr"
1797 AST_MODULE_INFO(ASTERISK_GPL_KEY,
1798 AST_MODFLAG_DEFAULT,
1799 "Channel driver for LCR",
1800 .load = load_module,
1801 .unload = unload_module,
1802 .reload = reload_module,