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 #warning reconnect after socket closed, release all calls.
83 #warning debug of call handling
84 #warning ausloesen beim socket-verlust
92 #include <sys/types.h>
96 #include <sys/ioctl.h>
97 #include <sys/socket.h>
100 #include <semaphore.h>
102 #include <asterisk/module.h>
103 #include <asterisk/channel.h>
104 #include <asterisk/config.h>
105 #include <asterisk/logger.h>
106 #include <asterisk/pbx.h>
107 #include <asterisk/options.h>
108 #include <asterisk/io.h>
109 #include <asterisk/frame.h>
110 #include <asterisk/translate.h>
111 #include <asterisk/cli.h>
112 #include <asterisk/musiconhold.h>
113 #include <asterisk/dsp.h>
114 #include <asterisk/translate.h>
115 #include <asterisk/file.h>
116 #include <asterisk/callerid.h>
117 #include <asterisk/indications.h>
118 #include <asterisk/app.h>
119 #include <asterisk/features.h>
120 #include <asterisk/sched.h>
122 #include "extension.h"
124 #include "lcrsocket.h"
126 #include "bchannel.h"
127 #include "chan_lcr.h"
128 #include "callerid.h"
130 CHAN_LCR_STATE // state description structure
135 char lcr_type[]="lcr";
138 ast_mutex_t chan_lock;
141 int glob_channel = 0;
146 struct admin_list *next;
147 struct admin_msg msg;
148 } *admin_first = NULL;
150 static struct ast_channel_tech lcr_tech;
153 * channel and call instances
155 struct chan_call *call_first;
157 struct chan_call *find_call_ref(unsigned long ref)
159 struct chan_call *call = call_first;
163 if (call->ref == ref)
171 struct chan_call *find_call_ast(struct ast_channel *ast)
173 struct chan_call *call = call_first;
177 if (call->ast == ast)
184 struct chan_call *find_call_handle(unsigned long handle)
186 struct chan_call *call = call_first;
190 if (call->bchannel_handle == handle)
198 struct chan_call *alloc_call(void)
200 struct chan_call **callp = &call_first;
203 callp = &((*callp)->next);
205 *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
207 memset(*callp, 0, sizeof(struct chan_call));
211 void free_call(struct chan_call *call)
213 struct chan_call **temp = &call_first;
219 *temp = (*temp)->next;
222 if (call->bchannel->call)
223 call->bchannel->call = NULL;
225 if (call->bridge_call)
227 if (call->bridge_call->bridge_call)
228 call->bridge_call->bridge_call = NULL;
233 temp = &((*temp)->next);
237 unsigned short new_bridge_id(void)
239 struct chan_call *call;
240 unsigned short id = 1;
242 /* search for lowest bridge id that is not in use and not 0 */
248 if (call->bridge_id == id)
261 * receive bchannel data
263 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
267 void rx_dtmf(struct bchannel *bchannel, char tone)
272 * enque message to LCR
274 int send_message(int message_type, unsigned long ref, union parameter *param)
276 struct admin_list *admin, **adminp;
278 adminp = &admin_first;
280 adminp = &((*adminp)->next);
281 admin = (struct admin_list *)malloc(sizeof(struct admin_list));
284 admin->msg.type = message_type;
285 admin->msg.ref = ref;
286 memcpy(&admin->msg.param, param, sizeof(union parameter));
292 * send setup info to LCR
293 * this function is called, when asterisk call is received and ref is received
295 static void send_setup_to_lcr(struct chan_call *call)
297 union parameter newparam;
298 struct ast_channel *ast = call->ast;
300 if (!call->ast || !call->ref)
303 /* send setup message to LCR */
304 memset(&newparam, 0, sizeof(union parameter));
305 newparam.setup.callerinfo.itype = INFO_ITYPE_CHAN;
306 newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
307 if (ast->cid.cid_num) if (ast->cid.cid_num[0])
308 strncpy(newparam.setup.callerinfo.id, ast->cid.cid_num, sizeof(newparam.setup.callerinfo.id)-1);
309 if (ast->cid.cid_name) if (ast->cid.cid_name[0])
310 strncpy(newparam.setup.callerinfo.name, ast->cid.cid_name, sizeof(newparam.setup.callerinfo.name)-1);
311 if (ast->cid.cid_rdnis) if (ast->cid.cid_rdnis[0])
313 strncpy(newparam.setup.redirinfo.id, ast->cid.cid_rdnis, sizeof(newparam.setup.redirinfo.id)-1);
314 newparam.setup.redirinfo.itype = INFO_ITYPE_CHAN;
315 newparam.setup.redirinfo.ntype = INFO_NTYPE_UNKNOWN;
317 switch(ast->cid.cid_pres & AST_PRES_RESTRICTION)
319 case AST_PRES_ALLOWED:
320 newparam.setup.callerinfo.present = INFO_PRESENT_ALLOWED;
322 case AST_PRES_RESTRICTED:
323 newparam.setup.callerinfo.present = INFO_PRESENT_RESTRICTED;
325 case AST_PRES_UNAVAILABLE:
326 newparam.setup.callerinfo.present = INFO_PRESENT_NOTAVAIL;
329 newparam.setup.callerinfo.present = INFO_PRESENT_NULL;
331 switch(ast->cid.cid_ton)
334 newparam.setup.callerinfo.ntype = INFO_NTYPE_SUBSCRIBER;
337 newparam.setup.callerinfo.ntype = INFO_NTYPE_NATIONAL;
340 newparam.setup.callerinfo.ntype = INFO_NTYPE_INTERNATIONAL;
343 newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
345 newparam.setup.capainfo.bearer_capa = ast->transfercapability;
347 // newparam.setup.capainfo.bearer_user = alaw 3, ulaw 2;
348 newparam.setup.capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
349 newparam.setup.capainfo.hlc = INFO_HLC_NONE;
350 newparam.setup.capainfo.exthlc = INFO_HLC_NONE;
351 send_message(MESSAGE_SETUP, call->ref, &newparam);
353 /* change to outgoing setup state */
354 call->state = CHAN_LCR_STATE_OUT_SETUP;
358 * send dialing info to LCR
359 * this function is called, when setup acknowledge is received and dialing
362 static void send_dialque_to_lcr(struct chan_call *call)
364 union parameter newparam;
366 if (!call->ast || !call->ref || !call->dialque)
369 /* send setup message to LCR */
370 memset(&newparam, 0, sizeof(union parameter));
371 strncpy(newparam.information.id, call->dialque, sizeof(newparam.information.id)-1);
372 call->dialque[0] = '\0';
373 send_message(MESSAGE_INFORMATION, call->ref, &newparam);
377 * in case of a bridge, the unsupported message can be forwarded directly
378 * to the remote call.
380 static void bridge_message_if_bridged(struct chan_call *call, int message_type, union parameter *param)
384 if (!call->bridge_call) return;
385 send_message(MESSAGE_RELEASE, call->bridge_call->ref, param);
389 * incoming setup from LCR
391 static void lcr_in_setup(struct chan_call *call, int message_type, union parameter *param)
393 struct ast_channel *ast;
394 union parameter newparam;
396 /* create asterisk channel instrance */
397 #warning anstatt vom lcr "setup.exten" zu bekommen, sollten wir den context übertragen, der dann in der channel.conf zu dem richtigen ruleset führt.
398 ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
402 memset(&newparam, 0, sizeof(union parameter));
403 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
404 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
405 send_message(MESSAGE_RELEASE, call->ref, &newparam);
410 /* set ast pointer */
412 ast->tech_pvt = call;
413 ast->tech = &lcr_tech;
415 /* fill setup information */
416 if (param->setup.exten[0])
417 strncpy(ast->exten, param->setup.exten, AST_MAX_EXTENSION);
418 if (param->setup.callerinfo.id[0])
419 ast->cid.cid_num = strdup(param->setup.callerinfo.id);
420 if (param->setup.callerinfo.name[0])
421 ast->cid.cid_name = strdup(param->setup.callerinfo.name);
424 if (param->setup.redirinfo.id[0])
425 ast->cid.cid_name = strdup(numberrize_callerinfo(param->setup.callerinfo.name, param->setup.callerinfo.ntype, configfile->prefix_nat, configfile->prefix_inter));
427 switch (param->setup.callerinfo.present)
429 case INFO_PRESENT_ALLOWED:
430 ast->cid.cid_pres = AST_PRES_ALLOWED;
432 case INFO_PRESENT_RESTRICTED:
433 ast->cid.cid_pres = AST_PRES_RESTRICTED;
436 ast->cid.cid_pres = AST_PRES_UNAVAILABLE;
438 switch (param->setup.callerinfo.ntype)
440 case INFO_NTYPE_SUBSCRIBER:
441 ast->cid.cid_ton = 4;
443 case INFO_NTYPE_NATIONAL:
444 ast->cid.cid_ton = 2;
446 case INFO_NTYPE_INTERNATIONAL:
447 ast->cid.cid_ton = 1;
450 ast->cid.cid_ton = 0;
452 ast->transfercapability = param->setup.capainfo.bearer_capa;
454 /* configure channel */
457 ast->nativeformat = configfile->lawformat;
458 ast->readformat = ast->rawreadformat = configfile->lawformat;
459 ast->writeformat = ast->rawwriteformat = configfile->lawformat;
461 ast->hangupcause = 0;
464 call->state = CHAN_LCR_STATE_IN_SETUP;
466 /* send setup to asterisk */
469 /* send setup acknowledge to lcr */
470 memset(&newparam, 0, sizeof(union parameter));
471 send_message(MESSAGE_OVERLAP, call->ref, &newparam);
474 call->state = CHAN_LCR_STATE_IN_DIALING;
478 * incoming setup acknowledge from LCR
480 static void lcr_in_overlap(struct chan_call *call, int message_type, union parameter *param)
482 if (!call->ast) return;
484 /* send pending digits in dialque */
486 send_dialque_to_lcr(call);
487 /* change to overlap state */
488 call->state = CHAN_LCR_STATE_OUT_DIALING;
492 * incoming proceeding from LCR
494 static void lcr_in_proceeding(struct chan_call *call, int message_type, union parameter *param)
497 call->state = CHAN_LCR_STATE_OUT_PROCEEDING;
498 /* send event to asterisk */
500 ast_queue_control(call->ast, AST_CONTROL_PROCEEDING);
504 * incoming alerting from LCR
506 static void lcr_in_alerting(struct chan_call *call, int message_type, union parameter *param)
509 call->state = CHAN_LCR_STATE_OUT_ALERTING;
510 /* send event to asterisk */
512 ast_queue_control(call->ast, AST_CONTROL_RINGING);
516 * incoming connect from LCR
518 static void lcr_in_connect(struct chan_call *call, int message_type, union parameter *param)
521 call->state = CHAN_LCR_STATE_CONNECT;
522 /* copy connectinfo */
523 memcpy(&call->connectinfo, ¶m->connectinfo, sizeof(struct connect_info));
524 /* send event to asterisk */
526 ast_queue_control(call->ast, AST_CONTROL_ANSWER);
530 * incoming disconnect from LCR
532 static void lcr_in_disconnect(struct chan_call *call, int message_type, union parameter *param)
534 struct ast_channel *ast = call->ast;
535 union parameter newparam;
538 call->state = CHAN_LCR_STATE_IN_DISCONNECT;
540 call->cause = param->disconnectinfo.cause;
541 call->location = param->disconnectinfo.location;
542 /* if bridge, forward disconnect and return */
543 if (call->bridge_call)
545 bridge_message_if_bridged(call, message_type, param);
549 newparam.disconnectinfo.cause = CAUSE_NORMAL;
550 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
551 send_message(MESSAGE_RELEASE, call->ref, &newparam);
553 /* release asterisk */
554 ast->hangupcause = call->cause;
555 ast_queue_hangup(ast);
556 /* change to release state */
557 call->state = CHAN_LCR_STATE_RELEASE;
561 * incoming setup acknowledge from LCR
563 static void lcr_in_release(struct chan_call *call, int message_type, union parameter *param)
565 struct ast_channel *ast = call->ast;
569 /* change to release state */
570 call->state = CHAN_LCR_STATE_RELEASE;
571 /* copy release info */
574 call->cause = param->disconnectinfo.cause;
575 call->location = param->disconnectinfo.location;
577 /* if we have an asterisk instance, send hangup, else we are done */
580 ast->hangupcause = call->cause;
581 ast_queue_hangup(ast);
590 * incoming information from LCR
592 static void lcr_in_information(struct chan_call *call, int message_type, union parameter *param)
597 if (!call->ast) return;
600 p = param->information.id;
601 if (call->state == CHAN_LCR_STATE_IN_DIALING && *p)
605 /* send digit to asterisk */
606 memset(&fr, 0, sizeof(fr));
607 fr.frametype = AST_FRAME_DTMF;
609 fr.delivery = ast_tv(0, 0);
610 ast_queue_frame(call->ast, &fr);
614 /* use bridge to forware message not supported by asterisk */
615 if (call->state == CHAN_LCR_STATE_CONNECT)
616 bridge_message_if_bridged(call, message_type, param);
620 * incoming information from LCR
622 static void lcr_in_notify(struct chan_call *call, int message_type, union parameter *param)
624 if (!call->ast) return;
626 /* use bridge to forware message not supported by asterisk */
627 bridge_message_if_bridged(call, message_type, param);
631 * incoming information from LCR
633 static void lcr_in_facility(struct chan_call *call, int message_type, union parameter *param)
635 if (!call->ast) return;
637 /* use bridge to forware message not supported by asterisk */
638 bridge_message_if_bridged(call, message_type, param);
642 * message received from LCR
644 int receive_message(int message_type, unsigned long ref, union parameter *param)
646 union parameter newparam;
647 struct bchannel *bchannel;
648 struct chan_call *call;
650 memset(&newparam, 0, sizeof(union parameter));
652 /* handle bchannel message*/
653 if (message_type == MESSAGE_BCHANNEL)
655 switch(param->bchannel.type)
657 case BCHANNEL_ASSIGN:
658 if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
660 fprintf(stderr, "error: bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
663 /* create bchannel */
664 bchannel = alloc_bchannel(param->bchannel.handle);
667 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
671 /* configure channel */
672 bchannel->b_tx_gain = param->bchannel.tx_gain;
673 bchannel->b_rx_gain = param->bchannel.rx_gain;
674 strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
675 if (param->bchannel.crypt_len)
677 bchannel->b_crypt_len = param->bchannel.crypt_len;
678 bchannel->b_crypt_type = param->bchannel.crypt_type;
679 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
681 bchannel->b_txdata = 0;
682 bchannel->b_dtmf = 1;
683 bchannel->b_tx_dejitter = 1;
685 /* in case, ref is not set, this bchannel instance must
686 * be created until it is removed again by LCR */
688 if ((call = find_call_ref(ref)))
690 bchannel->call = call;
691 call->bchannel = bchannel;
692 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
694 bchannel_join(bchannel, call->bridge_id);
696 if (bchannel_create(bchannel))
697 bchannel_activate(bchannel, 1);
700 newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
701 newparam.bchannel.handle = param->bchannel.handle;
702 send_message(MESSAGE_BCHANNEL, 0, &newparam);
705 case BCHANNEL_REMOVE:
706 if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
708 #warning alle fprintf nach ast_log
709 fprintf(stderr, "error: bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
712 /* unklink from call and destroy bchannel */
713 free_bchannel(bchannel);
716 newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
717 newparam.bchannel.handle = param->bchannel.handle;
718 send_message(MESSAGE_BCHANNEL, 0, &newparam);
723 fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
729 if (message_type == MESSAGE_NEWREF)
731 if (param->direction)
733 /* new ref from lcr */
734 if (!ref || find_call_ref(ref))
736 fprintf(stderr, "illegal new ref %ld received\n", ref);
739 /* allocate new call instance */
742 call->state = CHAN_LCR_STATE_IN_PREPARE;
745 /* wait for setup (or release from asterisk) */
748 /* new ref, as requested from this remote application */
749 call = find_call_ref(0);
752 /* send release, if ref does not exist */
753 newparam.disconnectinfo.cause = CAUSE_NORMAL;
754 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
755 send_message(MESSAGE_RELEASE, ref, &newparam);
760 /* send pending setup info */
761 if (call->state == CHAN_LCR_STATE_OUT_PREPARE)
762 send_setup_to_lcr(call);
763 /* release if asterisk has signed off */
764 else if (call->state == CHAN_LCR_STATE_RELEASE)
769 newparam.disconnectinfo.cause = call->cause;
770 newparam.disconnectinfo.location = call->location;
773 newparam.disconnectinfo.cause = 16;
774 newparam.disconnectinfo.location = 5;
776 send_message(MESSAGE_RELEASE, ref, &newparam);
788 fprintf(stderr, "received message %d without ref\n", message_type);
791 call = find_call_ref(ref);
794 /* ignore ref that is not used (anymore) */
798 /* handle messages */
802 lcr_in_setup(call, message_type, param);
805 case MESSAGE_OVERLAP:
806 lcr_in_overlap(call, message_type, param);
809 case MESSAGE_PROCEEDING:
810 lcr_in_proceeding(call, message_type, param);
813 case MESSAGE_ALERTING:
814 lcr_in_alerting(call, message_type, param);
817 case MESSAGE_CONNECT:
818 lcr_in_connect(call, message_type, param);
821 case MESSAGE_DISCONNECT:
822 lcr_in_disconnect(call, message_type, param);
825 case MESSAGE_RELEASE:
826 lcr_in_release(call, message_type, param);
829 case MESSAGE_INFORMATION:
830 lcr_in_information(call, message_type, param);
834 lcr_in_notify(call, message_type, param);
837 case MESSAGE_FACILITY:
838 lcr_in_facility(call, message_type, param);
841 case MESSAGE_PATTERN:
845 case MESSAGE_NOPATTERN:
849 case MESSAGE_AUDIOPATH:
862 * warning! not thread safe
863 * returns -1 for socket error, 0 for no work, 1 for work
865 int handle_socket(void)
869 struct admin_message msg;
870 struct admin_list *admin;
874 #warning SOCKET FEHLT!
875 /* read from socket */
876 len = read(sock, &msg, sizeof(msg));
879 printf("Socket closed\n");
880 return(-1); // socket closed
884 if (len != sizeof(msg))
886 fprintf(stderr, "Socket short read (%d)\n", len);
887 return(-1); // socket error
889 if (msg.message != ADMIN_MESSAGE)
891 fprintf(stderr, "Socket received illegal message %d\n", msg.message);
892 return(-1); // socket error
894 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
895 printf("message received %d\n", msg.u.msg.type);
899 if (errno != EWOULDBLOCK)
901 fprintf(stderr, "Socket error %d\n", errno);
906 /* write to socket */
910 len = write(sock, &admin->msg, sizeof(msg));
913 printf("Socket closed\n");
914 return(-1); // socket closed
918 if (len != sizeof(msg))
920 fprintf(stderr, "Socket short write (%d)\n", len);
921 return(-1); // socket error
924 admin_first = admin->next;
930 if (errno != EWOULDBLOCK)
932 fprintf(stderr, "Socket error %d\n", errno);
941 * open and close socket and thread
943 int open_socket(void)
947 char *socket_name = SOCKET_NAME;
949 struct sockaddr_un sock_address;
950 unsigned long on = 1;
951 union parameter param;
954 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
956 ast_log(LOG_ERROR, "Failed to create socket.\n");
960 /* set socket address and name */
961 memset(&sock_address, 0, sizeof(sock_address));
962 sock_address.sun_family = PF_UNIX;
963 strcpy(sock_address.sun_path, socket_name);
966 if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
969 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
973 /* set non-blocking io */
974 if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
977 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
981 /* enque hello message */
982 memset(¶m, 0, sizeof(param));
983 strcpy(param.hello.application, "asterisk");
984 send_message(MESSAGE_HELLO, 0, ¶m);
989 void close_socket(int sock)
996 static void *chan_thread(void *arg)
1000 ast_mutex_lock(&chan_lock);
1007 int ret = handle_socket();
1014 ret = bchannel_handle();
1020 ast_mutex_unlock(&chan_lock);
1022 ast_mutex_lock(&chan_lock);
1026 ast_mutex_unlock(&chan_lock);
1032 * new asterisk instance
1034 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
1036 union parameter newparam;
1037 struct ast_channel *ast;
1038 struct chan_call *call;
1040 ast_mutex_lock(&chan_lock);
1042 /* create call instance */
1043 call = alloc_call();
1046 /* failed to create instance */
1049 /* create asterisk channel instrance */
1050 ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
1054 /* failed to create instance */
1058 ast->tech_pvt = call;
1060 ast->tech = &lcr_tech;
1061 /* configure channel */
1062 snprintf(ast->name, sizeof(ast->name), "%s/%d", lcr_type, ++glob_channel);
1063 ast->name[sizeof(ast->name)-1] = '\0';
1066 ast->nativeformat = configfile->lawformat;
1067 ast->readformat = ast->rawreadformat = configfile->lawformat;
1068 ast->writeformat = ast->rawwriteformat = configfile->lawformat;
1070 ast->hangupcause = 0;
1071 /* send MESSAGE_NEWREF */
1072 memset(&newparam, 0, sizeof(union parameter));
1073 newparam.direction = 0; /* request from app */
1074 send_message(MESSAGE_NEWREF, 0, &newparam);
1076 call->state = CHAN_LCR_STATE_OUT_PREPARE;
1078 ast_mutex_unlock(&chan_lock);
1084 * call from asterisk
1086 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
1088 struct chan_call *call=ast->tech_pvt;
1090 if (!call) return -1;
1092 ast_mutex_lock(&chan_lock);
1094 #warning hier muss noch
1096 ast_copy_string(buf, dest, sizeof(buf)-1);
1098 port_str=strsep(&p, "/");
1099 dad=strsep(&p, "/");
1102 /* send setup message, if we already have a callref */
1104 send_setup_to_lcr(call);
1107 // ast_verbose("Call: ext:%s dest:(%s) -> dad(%s) \n", ast->exten,dest, dad);
1109 ast_mutex_unlock(&chan_lock);
1113 static int lcr_digit(struct ast_channel *ast, char digit)
1115 struct chan_call *call = ast->tech_pvt;
1116 union parameter newparam;
1119 if (!call) return -1;
1121 /* only pass IA5 number space */
1122 if (digit > 126 || digit < 32)
1125 ast_mutex_lock(&chan_lock);
1127 /* send information or queue them */
1128 if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING)
1130 memset(&newparam, 0, sizeof(union parameter));
1131 newparam.information.id[0] = digit;
1132 newparam.information.id[1] = '\0';
1133 send_message(MESSAGE_INFORMATION, call->ref, &newparam);
1136 && (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP));
1139 strncat(call->dialque, buf, strlen(call->dialque)-1);
1142 ast_mutex_unlock(&chan_lock);
1147 static int lcr_answer(struct ast_channel *ast)
1149 union parameter newparam;
1150 struct chan_call *call = ast->tech_pvt;
1152 if (!call) return -1;
1154 ast_mutex_lock(&chan_lock);
1156 /* copy connectinfo, if bridged */
1157 if (call->bridge_call)
1158 memcpy(&call->connectinfo, &call->bridge_call->connectinfo, sizeof(struct connect_info));
1159 /* send connect message to lcr */
1160 memset(&newparam, 0, sizeof(union parameter));
1161 memcpy(&newparam.connectinfo, &call->connectinfo, sizeof(struct connect_info));
1162 send_message(MESSAGE_CONNECT, call->ref, &newparam);
1164 call->state = CHAN_LCR_STATE_CONNECT;
1166 ast_mutex_unlock(&chan_lock);
1170 static int lcr_hangup(struct ast_channel *ast)
1172 union parameter newparam;
1173 struct chan_call *call = ast->tech_pvt;
1178 ast_mutex_lock(&chan_lock);
1179 /* disconnect asterisk, maybe not required */
1180 ast->tech_pvt = NULL;
1184 memset(&newparam, 0, sizeof(union parameter));
1185 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
1186 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1187 send_message(MESSAGE_RELEASE, call->ref, &newparam);
1190 ast_mutex_unlock(&chan_lock);
1194 /* ref is not set, due to prepare setup or release */
1195 if (call->state == CHAN_LCR_STATE_RELEASE)
1197 /* we get the response to our release */
1201 /* during prepare, we change to release state */
1202 call->state = CHAN_LCR_STATE_RELEASE;
1205 ast_mutex_unlock(&chan_lock);
1209 static int lcr_write(struct ast_channel *ast, struct ast_frame *f)
1211 struct chan_call *call = ast->tech_pvt;
1212 if (!call) return 0;
1213 ast_mutex_lock(&chan_lock);
1214 ast_mutex_unlock(&chan_lock);
1219 static struct ast_frame *lcr_read(struct ast_channel *ast)
1221 struct chan_call *call = ast->tech_pvt;
1222 if (!call) return 0;
1223 ast_mutex_lock(&chan_lock);
1224 ast_mutex_unlock(&chan_lock);
1228 static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, size_t datalen)
1230 struct chan_call *call = ast->tech_pvt;
1231 union parameter newparam;
1234 if (!call) return -1;
1236 ast_mutex_lock(&chan_lock);
1239 case AST_CONTROL_BUSY:
1240 /* send message to lcr */
1241 memset(&newparam, 0, sizeof(union parameter));
1242 newparam.disconnectinfo.cause = 17;
1243 newparam.disconnectinfo.location = 5;
1244 send_message(MESSAGE_DISCONNECT, call->ref, &newparam);
1246 call->state = CHAN_LCR_STATE_OUT_DISCONNECT;
1248 ast_mutex_unlock(&chan_lock);
1250 case AST_CONTROL_CONGESTION:
1252 ast_mutex_unlock(&chan_lock);
1254 case AST_CONTROL_RINGING:
1255 /* send message to lcr */
1256 memset(&newparam, 0, sizeof(union parameter));
1257 send_message(MESSAGE_ALERTING, call->ref, &newparam);
1259 call->state = CHAN_LCR_STATE_OUT_ALERTING;
1261 ast_mutex_unlock(&chan_lock);
1265 ast_mutex_unlock(&chan_lock);
1268 case AST_CONTROL_VIDUPDATE:
1271 case AST_CONTROL_HOLD:
1272 /* send message to lcr */
1273 memset(&newparam, 0, sizeof(union parameter));
1274 newparam.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
1275 send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1277 case AST_CONTROL_UNHOLD:
1278 /* send message to lcr */
1279 memset(&newparam, 0, sizeof(union parameter));
1280 newparam.notifyinfo.notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
1281 send_message(MESSAGE_NOTIFY, call->ref, &newparam);
1285 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, ast->name);
1287 ast_mutex_unlock(&chan_lock);
1292 ast_mutex_unlock(&chan_lock);
1299 enum ast_bridge_result lcr_bridge(struct ast_channel *ast1,
1300 struct ast_channel *ast2, int flags,
1301 struct ast_frame **fo,
1302 struct ast_channel **rc, int timeoutms)
1305 struct chan_call *call1, *call2;
1306 struct ast_channel *carr[2], *who;
1308 struct ast_frame *f;
1312 if (config nobridge) {
1313 ast_log(LOG_NOTICE, "Falling back to Asterisk bridging\n");
1314 return AST_BRIDGE_FAILED;
1317 if (! (flags&AST_BRIDGE_DTMF_CHANNEL_0) )
1318 call1->ignore_dtmf=1;
1320 if (! (flags&AST_BRIDGE_DTMF_CHANNEL_1) )
1321 call2->ignore_dtmf=1;
1324 /* join via dsp (if the channels are currently open) */
1325 bridge_id = new_bridge_id();
1326 ast_mutex_lock(&chan_lock);
1327 call1 = ast1->tech_pvt;
1328 call2 = ast2->tech_pvt;
1331 call1->bridge_id = bridge_id;
1332 if (call1->bchannel)
1333 bchannel_join(call1->bchannel, bridge_id);
1337 call2->bridge_id = bridge_id;
1338 if (call2->bchannel)
1339 bchannel_join(call2->bchannel, bridge_id);
1341 ast_mutex_unlock(&chan_lock);
1344 who = ast_waitfor_n(carr, 2, &to);
1347 ast_log(LOG_NOTICE,"misdn_bridge: empty read, breaking out\n");
1352 if (!f || f->frametype == AST_FRAME_CONTROL) {
1359 if ( f->frametype == AST_FRAME_DTMF ) {
1365 #warning kann einfach gesendet werden. dsp slittet automatisch, wenn frames kommen, bis der fifo leer ist.
1367 if (f->frametype == AST_FRAME_VOICE) {
1382 /* split channels */
1383 ast_mutex_lock(&chan_lock);
1384 call1 = ast1->tech_pvt;
1385 call2 = ast2->tech_pvt;
1388 call1->bridge_id = 0;
1389 if (call1->bchannel)
1390 bchannel_join(call1->bchannel, 0);
1394 call2->bridge_id = 0;
1395 if (call2->bchannel)
1396 bchannel_join(call2->bchannel, 0);
1398 ast_mutex_unlock(&chan_lock);
1401 return AST_BRIDGE_COMPLETE;
1403 static struct ast_channel_tech lcr_tech = {
1405 .description="Channel driver for connecting to Linux-Call-Router",
1406 .capabilities=AST_FORMAT_ALAW,
1407 .requester=lcr_request,
1408 .send_digit_begin=lcr_digit,
1415 .indicate=lcr_indicate,
1416 // .fixup=lcr_fixup,
1417 // .send_text=lcr_send_text,
1425 static int lcr_show_lcr (int fd, int argc, char *argv[])
1430 static int lcr_show_calls (int fd, int argc, char *argv[])
1435 static int lcr_reload_routing (int fd, int argc, char *argv[])
1440 static int lcr_reload_interfaces (int fd, int argc, char *argv[])
1445 static int lcr_port_block (int fd, int argc, char *argv[])
1450 static int lcr_port_unblock (int fd, int argc, char *argv[])
1455 static int lcr_port_unload (int fd, int argc, char *argv[])
1460 static struct ast_cli_entry cli_show_lcr =
1461 { {"lcr", "show", "lcr", NULL},
1463 "Shows current states of LCR core",
1464 "Usage: lcr show lcr\n",
1467 static struct ast_cli_entry cli_show_calls =
1468 { {"lcr", "show", "calls", NULL},
1470 "Shows current calls made by LCR and Asterisk",
1471 "Usage: lcr show calls\n",
1474 static struct ast_cli_entry cli_reload_routing =
1475 { {"lcr", "reload", "routing", NULL},
1477 "Reloads routing conf of LCR, current uncomplete calls will be disconnected",
1478 "Usage: lcr reload routing\n",
1481 static struct ast_cli_entry cli_reload_interfaces =
1482 { {"lcr", "reload", "interfaces", NULL},
1483 lcr_reload_interfaces,
1484 "Reloads interfaces conf of LCR",
1485 "Usage: lcr reload interfaces\n",
1488 static struct ast_cli_entry cli_port_block =
1489 { {"lcr", "port", "block", NULL},
1491 "Blocks LCR port for further calls",
1492 "Usage: lcr port block \"<port>\"\n",
1495 static struct ast_cli_entry cli_port_unblock =
1496 { {"lcr", "port", "unblock", NULL},
1498 "Unblocks or loads LCR port, port is opened my mISDN",
1499 "Usage: lcr port unblock \"<port>\"\n",
1502 static struct ast_cli_entry cli_port_unload =
1503 { {"lcr", "port", "unload", NULL},
1505 "Unloads LCR port, port is closes by mISDN",
1506 "Usage: lcr port unload \"<port>\"\n",
1511 * module loading and destruction
1513 int load_module(void)
1515 // ast_mutex_init(&release_lock);
1517 // lcr_cfg_update_ptp();
1519 ast_mutex_init(&chan_lock);
1521 if (!(lcr_sock = open_socket())) {
1522 ast_log(LOG_ERROR, "Unable to connect\n");
1524 /* continue with closed socket */
1527 if (!bchannel_initialize()) {
1528 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
1529 close_socket(lcr_sock);
1534 if (ast_channel_register(&lcr_tech)) {
1535 ast_log(LOG_ERROR, "Unable to register channel class\n");
1536 bchannel_deinitialize();
1537 close_socket(lcr_sock);
1542 ast_cli_register(&cli_show_lcr);
1543 ast_cli_register(&cli_show_calls);
1545 ast_cli_register(&cli_reload_routing);
1546 ast_cli_register(&cli_reload_interfaces);
1547 ast_cli_register(&cli_port_block);
1548 ast_cli_register(&cli_port_unblock);
1549 ast_cli_register(&cli_port_unload);
1551 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
1552 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
1553 "Sets mISDN opts. and optargs\n"
1555 "The available options are:\n"
1556 " d - Send display text on called phone, text is the optparam\n"
1557 " n - don't detect dtmf tones on called channel\n"
1558 " h - make digital outgoing call\n"
1559 " c - make crypted outgoing call, param is keyindex\n"
1560 " e - perform echo cancelation on this channel,\n"
1561 " takes taps as arguments (32,64,128,256)\n"
1562 " s - send Non Inband DTMF as inband\n"
1563 " vr - rxgain control\n"
1564 " vt - txgain control\n"
1568 lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1570 chan_lcr_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
1572 //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1576 if ((pthread_create(&chan_tid, NULL, chan_thread, NULL)<0))
1578 /* failed to create thread */
1579 bchannel_deinitialize();
1580 close_socket(lcr_sock);
1581 ast_channel_unregister(&lcr_tech);
1587 int unload_module(void)
1589 /* First, take us out of the channel loop */
1590 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
1593 pthread_join(chan_tid, NULL);
1595 ast_channel_unregister(&lcr_tech);
1597 if (mISDN_created) {
1598 bchannel_deinitialize();
1602 if (lcr_sock >= 0) {
1610 static int reload_module(void)
1617 ast_mutex_t usecnt_lock;
1623 ast_mutex_lock(&usecnt_lock);
1625 ast_mutex_unlock(&usecnt_lock);
1630 char *desc="Channel driver for lcr";
1632 char *description(void)
1639 return ASTERISK_GPL_KEY;
1642 #define AST_MODULE "chan_lcr"
1643 AST_MODULE_INFO(ASTERISK_GPL_KEY,
1644 AST_MODFLAG_DEFAULT,
1645 "Channel driver for LCR",
1646 .load = load_module,
1647 .unload = unload_module,
1648 .reload = reload_module,