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 locking asterisk process and handler
83 reconnect after socket closed, release all calls.
84 debug of call handling
85 denke an alle info-elements in jeder message (from asterisk & from lcr)
86 ausloesen beim socket-verlust
88 bei "ast_channel_alloc" kannste die Callerid und den type usw. setzten.
89 da kannste auch die calledPartyNum setzen. Um asterisk ein Setup zu schicken rufst du einfach "ast_pbx_start( channel ) " auf. Die ganzen queue baren indications und Controls findest du in "include/asterisk/frame.h"
93 Messages die zum Asterisk gehen:
95 SETUP - > ast_pbx_start(ast)
96 CONNECT -> ast_queue_control(ast,
98 PROCEEDING -> ast_queue_control(ast,
99 AST_CONTROL_PROCEEDING);
100 ALERTING -> ast_queue_control(ast,
101 AST_CONTROL_RINGING);
102 DISCONNECT -> ast_queue_hangup(ast);
104 Messages die vom Asterisk kommen:
106 lcr_request -> NEWREF
108 lcr_answer -> CONNECT
109 lcr_hangup -> RELEASE_(complete)
110 lcr_indicate(AST_CONTROL_RINGING) -> ALERTING
111 lcr_indicate(AST_CONTROL_PROCEEDING) -> PROCEEDING
112 lcr_indicate(AST_CONTROL_PROGRESS) -> PROGRESS
113 lcr_indicate(AST_CONTROL_BUSY) -> DISCONNECT ( cause=17 )
128 #include <sys/types.h>
132 #include <sys/ioctl.h>
133 #include <sys/socket.h>
137 #include <semaphore.h>
139 #include "extension.h"
141 #include "lcrsocket.h"
143 #include "bchannel.h"
144 #include "chan_lcr.h"
148 #include <asterisk/module.h>
149 #include <asterisk/channel.h>
150 #include <asterisk/config.h>
151 #include <asterisk/logger.h>
152 #include <asterisk/pbx.h>
153 #include <asterisk/options.h>
154 #include <asterisk/io.h>
155 #include <asterisk/frame.h>
156 #include <asterisk/translate.h>
157 #include <asterisk/cli.h>
158 #include <asterisk/musiconhold.h>
159 #include <asterisk/dsp.h>
160 #include <asterisk/translate.h>
161 #include <asterisk/file.h>
162 #include <asterisk/callerid.h>
163 #include <asterisk/indications.h>
164 #include <asterisk/app.h>
165 #include <asterisk/features.h>
166 #include <asterisk/sched.h>
168 CHAN_LCR_STATE // state description structure
173 char lcr_type[]="LCR";
176 pthread_mutex_t chan_lock;
182 struct admin_list *next;
183 struct admin_msg msg;
184 } *admin_first = NULL;
187 * channel and call instances
189 struct chan_call *call_first;
191 struct chan_call *find_call_ref(unsigned long ref)
193 struct chan_call *call = call_first;
197 if (call->ref == ref)
204 struct chan_call *find_call_handle(unsigned long handle)
206 struct chan_call *call = call_first;
210 if (call->bchannel_handle == handle)
217 struct chan_call *alloc_call(void)
219 struct chan_call **callp = &call_first;
222 callp = &((*callp)->next);
224 *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
226 memset(*callp, 0, sizeof(struct chan_call));
230 void free_call(struct chan_call *call)
232 struct chan_call **temp = &call_first;
238 *temp = (*temp)->next;
242 temp = &((*temp)->next);
246 unsigned short new_brige_id(void)
248 struct chan_call *call;
249 unsigned short id = 1;
251 /* search for lowest bridge id that is not in use and not 0 */
257 if (call->bridge_id == id)
270 * receive bchannel data
272 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
276 void rx_dtmf(struct bchannel *bchannel, char tone)
281 * enque message to LCR
283 int send_message(int message_type, unsigned long ref, union parameter *param)
285 struct admin_list *admin, **adminp;
287 adminp = &admin_first;
289 adminp = &((*adminp)->next);
290 admin = (struct admin_list *)malloc(sizeof(struct admin_list));
293 admin->msg.type = message_type;
294 admin->msg.ref = ref;
295 memcpy(&admin->msg.param, param, sizeof(union parameter));
301 * incoming setup from LCR
303 static void lcr_in_setup(struct chan_call *call, int message_type, union parameter *param)
305 struct ast_channel *ast;
306 union parameter newparam;
308 /* create asterisk channel instrance */
309 ast = ast_channel_alloc(1);
313 memset(&newparam, 0, sizeof(union parameter));
314 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
315 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
316 send_message(MESSAGE_RELEASE, call->ref, &newparam);
321 /* set ast pointer */
324 /* fill setup information */
325 #warning todo: setup-info reinschreiben
327 /* send setup to asterisk */
328 #warning todo: setup bei der asterisk triggern
331 call->state = CHAN_LCR_STATE_IN_SETUP;
335 * incoming setup acknowledge from LCR
337 static void lcr_in_overlap(struct chan_call *call, int message_type, union parameter *param)
339 /* send pending digits in dialque */
341 send_dialing_to_lcr(call);
342 /* change to overlap state */
343 call->state = CHAN_LCR_STATE_OUT_DIALING;
347 * incoming proceeding from LCR
349 static void lcr_in_proceeding(struct chan_call *call, int message_type, union parameter *param)
352 call->state = CHAN_LCR_STATE_OUT_PROCEEDING;
353 /* send event to asterisk */
358 * incoming alerting from LCR
360 static void lcr_in_alerting(struct chan_call *call, int message_type, union parameter *param)
363 call->state = CHAN_LCR_STATE_OUT_ALERTING;
364 /* send event to asterisk */
369 * incoming connect from LCR
371 static void lcr_in_connect(struct chan_call *call, int message_type, union parameter *param)
374 call->state = CHAN_LCR_STATE_CONNECT;
375 /* copy connectinfo */
377 /* send event to asterisk */
382 * incoming disconnect from LCR
384 static void lcr_in_disconnect(struct chan_call *call, int message_type, union parameter *param)
387 call->state = CHAN_LCR_STATE_IN_DISCONNECT;
388 /* copy disconnect info */
390 /* send event to asterisk */
395 * incoming setup acknowledge from LCR
397 static void lcr_in_release(struct chan_call *call, int message_type, union parameter *param)
401 /* change to release state */
402 call->state = CHAN_LCR_STATE_RELEASE;
403 /* copy release info */
405 /* if we have an asterisk instance, send hangup, else we are done */
408 ast_queue_hangup(call->ast);
417 * incoming information from LCR
419 static void lcr_in_information(struct chan_call *call, int message_type, union parameter *param)
422 todo and write them, maybe queue them for asterisk
423 /* send event to asterisk */
428 * incoming information from LCR
430 static void lcr_in_facility(struct chan_call *call, int message_type, union parameter *param)
432 /* copy progress info */
433 todo and write them, maybe queue them for asterisk
434 /* send event to asterisk */
436 or maybe use bride info to forward facility.
440 * message received from LCR
442 int receive_message(int message_type, unsigned long ref, union parameter *param)
444 union parameter newparam;
445 struct bchannel *bchannel;
446 struct chan_call *call;
448 memset(&newparam, 0, sizeof(union parameter));
450 /* handle bchannel message*/
451 if (message_type == MESSAGE_BCHANNEL)
453 switch(param->bchannel.type)
455 case BCHANNEL_ASSIGN:
456 if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
458 fprintf(stderr, "error: bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
461 /* create bchannel */
462 bchannel = alloc_bchannel(param->bchannel.handle);
465 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
469 /* configure channel */
470 bchannel->b_tx_gain = param->bchannel.tx_gain;
471 bchannel->b_rx_gain = param->bchannel.rx_gain;
472 strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
473 if (param->bchannel.crypt_len)
475 bchannel->b_crypt_len = param->bchannel.crypt_len;
476 bchannel->b_crypt_type = param->bchannel.crypt_type;
477 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
479 bchannel->b_txdata = 0;
480 bchannel->b_dtmf = 1;
481 bchannel->b_tx_dejitter = 1;
483 /* in case, ref is not set, this bchannel instance must
484 * be created until it is removed again by LCR */
486 if ((call = find_call_ref(ref)))
489 call->bchannel_handle = param->bchannel.handle;
490 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
491 bchannel_join(bchannel, call->bridge_id);
493 if (bchannel_create(bchannel))
494 bchannel_activate(bchannel, 1);
497 newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
498 newparam.bchannel.handle = param->bchannel.handle;
499 send_message(MESSAGE_BCHANNEL, 0, &newparam);
502 case BCHANNEL_REMOVE:
503 if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
505 #warning alle fprintf nach ast_log
506 fprintf(stderr, "error: bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
509 /* unlink from call */
510 if ((call = find_call_ref(bchannel->ref)))
512 call->bchannel_handle = 0;
514 /* destroy and remove bchannel */
515 free_bchannel(bchannel);
518 newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
519 newparam.bchannel.handle = param->bchannel.handle;
520 send_message(MESSAGE_BCHANNEL, 0, &newparam);
525 fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
531 if (message_type == MESSAGE_NEWREF)
533 if (param->direction)
535 /* new ref from lcr */
536 if (!ref || find_call_ref(ref))
538 fprintf(stderr, "illegal new ref %d received\n", ref);
541 /* allocate new call instance */
544 call->state = CHAN_LCR_STATE_IN_PREPARE;
547 /* wait for setup (or release from asterisk) */
550 /* new ref, as requested from this remote application */
551 call = find_call_ref(0);
554 /* send release, if ref does not exist */
555 newparam.disconnectinfo.cause = CAUSE_NORMAL;
556 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
557 send_message(MESSAGE_RELEASE, ref, &newparam);
562 /* send pending setup info */
563 if (call->state == CHAN_LCR_STATE_OUT_PREPARE)
564 send_setup_to_lcr(call);
565 /* release if asterisk has signed off */
566 else if (call->state == CHAN_LCR_STATE_RELEASE)
569 newparam.disconnectinfo.cause = todo
570 newparam.disconnectinfo.location = todo
571 send_message(MESSAGE_RELEASE, ref, &newparam);
583 fprintf(stderr, "received message %d without ref\n", message_type);
586 call = find_call_ref(ref);
589 /* ignore ref that is not used (anymore) */
593 /* handle messages */
597 lcr_in_setup(call, message_type, param);
600 case MESSAGE_OVERLAP:
601 lcr_in_overlap(call, message_type, param);
604 case MESSAGE_PROCEEDING:
605 lcr_in_proceeding(call, message_type, param);
608 case MESSAGE_ALERTING:
609 lcr_in_alerting(call, message_type, param);
612 case MESSAGE_CONNECT:
613 lcr_in_connect(call, message_type, param);
616 case MESSAGE_DISCONNECT:
617 lcr_in_disconnect(call, message_type, param);
620 case MESSAGE_RELEASE:
621 lcr_in_release(call, message_type, param);
624 case MESSAGE_INFORMATION:
625 lcr_in_disconnect(call, message_type, param);
628 case MESSAGE_FACILITY:
629 lcr_in_disconnect(call, message_type, param);
632 case MESSAGE_PATTERN:
636 case MESSAGE_NOPATTERN:
640 case MESSAGE_AUDIOPATH:
652 * warning! not thread safe
653 * returns -1 for socket error, 0 for no work, 1 for work
655 int handle_socket(void)
659 struct admin_message msg;
660 struct admin_list *admin;
664 #warning SOCKET FEHLT!
665 /* read from socket */
666 len = read(sock, &msg, sizeof(msg));
669 printf("Socket closed\n");
670 return(-1); // socket closed
674 if (len != sizeof(msg))
676 fprintf(stderr, "Socket short read (%d)\n", len);
677 return(-1); // socket error
679 if (msg.message != ADMIN_MESSAGE)
681 fprintf(stderr, "Socket received illegal message %d\n", msg.message);
682 return(-1); // socket error
684 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
685 printf("message received %d\n", msg.u.msg.type);
689 if (errno != EWOULDBLOCK)
691 fprintf(stderr, "Socket error %d\n", errno);
696 /* write to socket */
700 len = write(sock, &admin->msg, sizeof(msg));
703 printf("Socket closed\n");
704 return(-1); // socket closed
708 if (len != sizeof(msg))
710 fprintf(stderr, "Socket short write (%d)\n", len);
711 return(-1); // socket error
714 admin_first = admin->next;
720 if (errno != EWOULDBLOCK)
722 fprintf(stderr, "Socket error %d\n", errno);
731 * open and close socket
733 int open_socket(void)
737 char *socket_name = SOCKET_NAME;
739 struct sockaddr_un sock_address;
740 unsigned long on = 1;
741 union parameter param;
744 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
746 ast_log(LOG_ERROR, "Failed to create socket.\n");
750 /* set socket address and name */
751 memset(&sock_address, 0, sizeof(sock_address));
752 sock_address.sun_family = PF_UNIX;
753 strcpy(sock_address.sun_path, socket_name);
756 if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
759 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
763 /* set non-blocking io */
764 if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
767 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
771 /* enque hello message */
772 memset(¶m, 0, sizeof(param));
773 strcpy(param.hello.application, "asterisk");
774 send_message(MESSAGE_HELLO, 0, ¶m);
779 void close_socket(int sock)
787 socket muss per timer fuer das öffnen checken
788 static void *chan_thread(void *arg)
792 pthread_mutex_lock(&chan_lock);
799 int ret = handle_socket();
806 ret = bchannel_handle();
812 pthread_mutex_unlock(&chan_lock);
814 pthread_mutex_lock(&chan_lock);
818 pthread_mutex_unlock(&chan_lock);
824 * send setup info to LCR
825 * this function is called, when asterisk call is received and ref is received
827 static void send_setup_to_lcr(struct chan_call *call)
829 if (!ast || !call->ref)
832 /* send setup message to LCR */
833 memset(&newparam, 0, sizeof(union parameter));
834 newparam.setup.xxxxxx =
835 send_message(MESSAGE_SETUP, call->ref, &newparam);
836 /* change to outgoing setup state */
837 call->state = CHAN_LCR_STATE_OUT_SETUP;
841 CHRISTIAN: das war ein konflikt beim pullen
842 siehe anderes lcr_request();
843 bedenke: das ast_log muss noch üeberall eingepflegt werden
845 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
847 struct chan_call *call=alloc_call();
850 #warning hier muss jetzt wohl eine Ref angefordert werden!
851 ast=lcr_ast_new(call, ext, NULL, 0 );
856 ast_log(LOG_WARNING, "Could not create new Asterisk Channel\n");
860 ast_log(LOG_WARNING, "Could not create new Lcr Call Handle\n");
866 struct ast_channel *ast=NULL;
869 char *port_str, *ext, *p;
872 ast_copy_string(buf, data, sizeof(buf)-1);
874 port_str=strsep(&p, "/");
876 ast_verbose("portstr:%s ext:%s\n",port_str, ext);
878 sprintf(buf,"%s/%s",lcr_type,(char*)data);
882 * send dialing info to LCR
883 * this function is called, when setup acknowledge is received and dialing
886 static void send_dialing_to_lcr(struct chan_call *call)
888 if (!ast || !call->ref || !call->dialque)
891 /* send setup message to LCR */
892 memset(&newparam, 0, sizeof(union parameter));
893 strncpy(newparam.dialinginfo.id, call->dialque, sizeof(newparam.dialinginfo.id)-1);
894 call->dialque[0] = '\0';
895 send_message(MESSAGE_INFORMATION, call->ref, &newparam);
899 * new asterisk instance
901 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
903 pthread_mutex_lock(&chan_lock);
905 /* create call instance */
909 /* failed to create instance */
912 /* create asterisk channel instrance */
913 ast = ast_channel_alloc(1);
917 /* failed to create instance */
921 ast->tech_pvt = call;
923 /* send MESSAGE_NEWREF */
924 memset(&newparam, 0, sizeof(union parameter));
925 newparam.direction = 0; /* request from app */
926 send_message(MESSAGE_NEWREF, 0, &newparam);
928 call->state = CHAN_LCR_STATE_OUT_PREPARE;
930 pthread_mutex_unlock(&chan_lock);
936 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
938 struct chan_call *call=ast->tech_pvt;
940 char *port_str, *dad, *p;
942 if (!call) return -1;
944 pthread_mutex_lock(&chan_lock);
947 ast_copy_string(buf, dest, sizeof(buf)-1);
949 port_str=strsep(&p, "/");
952 /* send setup message, if we already have a callref */
954 send_setup_to_lcr(call);
957 ast_verbose("Call: ext:%s dest:(%s) -> dad(%s) \n", ast->exten,dest, dad);
959 #warning hier müssen wi eine der geholten REFs nehmen und ein SETUP schicken, die INFOS zum SETUP stehen im Ast pointer drin, bzw. werden hier übergeben.
961 pthread_mutex_unlock(&chan_lock);
965 static int lcr_digit(struct ast_channel *ast, char digit)
969 if (!call) return -1;
971 /* only pass IA5 number space */
972 if (digit > 126 || digit < 32)
975 pthread_mutex_lock(&chan_lock);
977 /* send information or queue them */
978 if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING)
980 send_dialing_to_lcr(call);
983 && (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP));
986 strncat(call->dialque, buf, strlen(char->dialque)-1);
989 digits kommen, koennen aber nicht verwendet werden.
990 sollen wir sie als info senden (im connect zb.)
993 pthread_mutex_unlock(&chan_lock);
998 static int lcr_answer(struct ast_channel *c)
1000 struct chan_call *call=c->tech_pvt;
1001 if (!call) return -1;
1002 pthread_mutex_lock(&chan_lock);
1003 pthread_mutex_unlock(&chan_lock);
1007 static int lcr_hangup(struct ast_channel *ast)
1009 struct chan_call *call = ast->tech_pvt;
1014 pthread_mutex_lock(&chan_lock);
1015 /* disconnect asterisk, maybe not required */
1016 ast->tech_pvt = NULL;
1020 memset(&newparam, 0, sizeof(union parameter));
1021 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
1022 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1023 send_message(MESSAGE_RELEASE, call->ref, &newparam);
1026 pthread_mutex_unlock(&chan_lock);
1030 /* ref is not set, due to prepare setup or release */
1031 if (call->state == CHAN_LCR_STATE_RELEASE)
1033 /* we get the response to our release */
1037 /* during prepare, we change to release state */
1038 call->state = CHAN_LCR_STATE_RELEASE;
1041 pthread_mutex_unlock(&chan_lock);
1045 static int lcr_write(struct ast_channel *c, struct ast_frame *f)
1047 struct chan_call *call= c->tech_pvt;
1048 if (!call) return 0;
1049 pthread_mutex_lock(&chan_lock);
1050 pthread_mutex_unlock(&chan_lock);
1054 static struct ast_frame *lcr_read(struct ast_channel *c)
1056 struct chan_call *call = c->tech_pvt;
1057 if (!call) return 0;
1058 pthread_mutex_lock(&chan_lock);
1059 pthread_mutex_unlock(&chan_lock);
1062 static int lcr_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
1065 if (!call) return -1;
1067 pthread_mutex_lock(&chan_lock);
1070 case AST_CONTROL_BUSY:
1071 case AST_CONTROL_CONGESTION:
1072 case AST_CONTROL_RINGING:
1073 pthread_mutex_unlock(&chan_lock);
1076 pthread_mutex_unlock(&chan_lock);
1079 case AST_CONTROL_VIDUPDATE:
1082 case AST_CONTROL_HOLD:
1083 ast_verbose(" << Console Has Been Placed on Hold >> \n");
1084 //ast_moh_start(c, data, g->mohinterpret);
1086 case AST_CONTROL_UNHOLD:
1087 ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
1092 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
1093 pthread_mutex_unlock(&chan_lock);
1097 pthread_mutex_unlock(&chan_lock);
1101 static struct ast_channel_tech lcr_tech = {
1103 .description="Channel driver for connecting to Linux-Call-Router",
1104 .capabilities=AST_FORMAT_ALAW,
1105 .requester=lcr_request,
1106 .send_digit=lcr_digit,
1108 // .bridge=lcr_bridge,
1113 .indicate=lcr_indicate,
1114 // .fixup=lcr_fixup,
1115 // .send_text=lcr_send_text,
1119 #warning das muss mal aus der config datei gelesen werden:
1120 char lcr_context[]="from-lcr";
1122 static struct ast_channel *lcr_ast_new(struct chan_call *call, char *exten, char *callerid, int ref)
1124 struct ast_channel *tmp;
1125 char *cid_name = 0, *cid_num = 0;
1129 ast_callerid_parse(callerid, &cid_name, &cid_num);
1131 tmp = ast_channel_alloc(1, AST_STATE_RESERVED, cid_num, cid_name, "", exten, "", 0, "%s/%d", lcr_type, ref);
1134 tmp->tech = &lcr_tech;
1135 tmp->writeformat = AST_FORMAT_ALAW;
1136 tmp->readformat = AST_FORMAT_ALAW;
1138 ast_copy_string(tmp->context, lcr_context, AST_MAX_CONTEXT);
1150 static int lcr_show_lcr (int fd, int argc, char *argv[])
1154 static int lcr_show_calls (int fd, int argc, char *argv[])
1158 static int lcr_reload_routing (int fd, int argc, char *argv[])
1162 static int lcr_reload_interfaces (int fd, int argc, char *argv[])
1166 static int lcr_port_block (int fd, int argc, char *argv[])
1170 static int lcr_port_unblock (int fd, int argc, char *argv[])
1174 static int lcr_port_unload (int fd, int argc, char *argv[])
1178 static struct ast_cli_entry cli_show_lcr =
1179 { {"lcr", "show", "lcr", NULL},
1181 "Shows current states of LCR core",
1182 "Usage: lcr show lcr\n",
1185 static struct ast_cli_entry cli_show_calls =
1186 { {"lcr", "show", "calls", NULL},
1188 "Shows current calls made by LCR and Asterisk",
1189 "Usage: lcr show calls\n",
1192 static struct ast_cli_entry cli_reload_routing =
1193 { {"lcr", "reload", "routing", NULL},
1195 "Reloads routing conf of LCR, current uncomplete calls will be disconnected",
1196 "Usage: lcr reload routing\n",
1199 static struct ast_cli_entry cli_reload_interfaces =
1200 { {"lcr", "reload", "interfaces", NULL},
1201 lcr_reload_interfaces,
1202 "Reloads interfaces conf of LCR",
1203 "Usage: lcr reload interfaces\n",
1206 static struct ast_cli_entry cli_port_block =
1207 { {"lcr", "port", "block", NULL},
1209 "Blocks LCR port for further calls",
1210 "Usage: lcr port block \"<port>\"\n",
1213 static struct ast_cli_entry cli_port_unblock =
1214 { {"lcr", "port", "unblock", NULL},
1216 "Unblocks or loads LCR port, port is opened my mISDN",
1217 "Usage: lcr port unblock \"<port>\"\n",
1220 static struct ast_cli_entry cli_port_unload =
1221 { {"lcr", "port", "unload", NULL},
1223 "Unloads LCR port, port is closes by mISDN",
1224 "Usage: lcr port unload \"<port>\"\n",
1229 * module loading and destruction
1231 int load_module(void)
1233 // ast_mutex_init(&release_lock);
1235 // lcr_cfg_update_ptp();
1237 pthread_mutex_init(&chan_lock, NULL);
1239 if (!(lcr_sock = open_socket())) {
1240 ast_log(LOG_ERROR, "Unable to connect\n");
1242 /* continue with closed socket */
1245 if (!bchannel_initialize()) {
1246 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
1247 close_socket(lcr_sock);
1252 if (ast_channel_register(&lcr_tech)) {
1253 ast_log(LOG_ERROR, "Unable to register channel class\n");
1254 bchannel_deinitialize();
1255 close_socket(lcr_sock);
1260 ast_cli_register(&cli_show_lcr);
1261 ast_cli_register(&cli_show_calls);
1263 ast_cli_register(&cli_reload_routing);
1264 ast_cli_register(&cli_reload_interfaces);
1265 ast_cli_register(&cli_port_block);
1266 ast_cli_register(&cli_port_unblock);
1267 ast_cli_register(&cli_port_unload);
1269 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
1270 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
1271 "Sets mISDN opts. and optargs\n"
1273 "The available options are:\n"
1274 " d - Send display text on called phone, text is the optparam\n"
1275 " n - don't detect dtmf tones on called channel\n"
1276 " h - make digital outgoing call\n"
1277 " c - make crypted outgoing call, param is keyindex\n"
1278 " e - perform echo cancelation on this channel,\n"
1279 " takes taps as arguments (32,64,128,256)\n"
1280 " s - send Non Inband DTMF as inband\n"
1281 " vr - rxgain control\n"
1282 " vt - txgain control\n"
1286 lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1288 chan_lcr_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
1290 //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1294 if ((pthread_create(&chan_tid, NULL, chan_thread, arg)<0))
1296 failed to create thread
1297 bchannel_deinitialize();
1298 close_socket(lcr_sock);
1299 ast_channel_unregister(&lcr_tech);
1305 int unload_module(void)
1307 /* First, take us out of the channel loop */
1308 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
1311 pthread_join(chan_tid, NULL);
1313 ast_channel_unregister(&lcr_tech);
1315 if (mISDN_created) {
1316 bchannel_deinitialize();
1320 if (lcr_sock >= 0) {
1328 static int reload_module(void)
1335 ast_mutex_t usecnt_lock;
1341 ast_mutex_lock(&usecnt_lock);
1343 ast_mutex_unlock(&usecnt_lock);
1348 char *desc="Channel driver for lcr";
1350 char *description(void)
1357 return ASTERISK_GPL_KEY;
1360 #define AST_MODULE "chan_lcr"
1361 AST_MODULE_INFO(ASTERISK_GPL_KEY,
1362 AST_MODFLAG_DEFAULT,
1363 "Channel driver for LCR",
1364 .load = load_module,
1365 .unload = unload_module,
1366 .reload = reload_module,