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
93 #include <sys/types.h>
97 #include <sys/ioctl.h>
98 #include <sys/socket.h>
102 #include <semaphore.h>
104 #include "extension.h"
106 #include "lcrsocket.h"
108 #include "bchannel.h"
109 #include "chan_lcr.h"
113 #include <asterisk/module.h>
114 #include <asterisk/channel.h>
115 #include <asterisk/config.h>
116 #include <asterisk/logger.h>
117 #include <asterisk/pbx.h>
118 #include <asterisk/options.h>
119 #include <asterisk/io.h>
120 #include <asterisk/frame.h>
121 #include <asterisk/translate.h>
122 #include <asterisk/cli.h>
123 #include <asterisk/musiconhold.h>
124 #include <asterisk/dsp.h>
125 #include <asterisk/translate.h>
126 #include <asterisk/file.h>
127 #include <asterisk/callerid.h>
128 #include <asterisk/indications.h>
129 #include <asterisk/app.h>
130 #include <asterisk/features.h>
131 #include <asterisk/sched.h>
133 CHAN_LCR_STATE // state description structure
138 char lcr_type[]="LCR";
141 pthread_mutex_t chan_lock;
147 struct admin_list *next;
148 struct admin_msg msg;
149 } *admin_first = NULL;
152 * channel and call instances
154 struct chan_call *call_first;
156 struct chan_call *find_call_ref(unsigned long ref)
158 struct chan_call *call = call_first;
162 if (call->ref == ref)
169 struct chan_call *find_call_handle(unsigned long handle)
171 struct chan_call *call = call_first;
175 if (call->bchannel_handle == handle)
182 struct chan_call *alloc_call(void)
184 struct chan_call **callp = &call_first;
187 callp = &((*callp)->next);
189 *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
191 memset(*callp, 0, sizeof(struct chan_call));
195 void free_call(struct chan_call *call)
197 struct chan_call **temp = &call_first;
203 *temp = (*temp)->next;
207 temp = &((*temp)->next);
211 unsigned short new_brige_id(void)
213 struct chan_call *call;
214 unsigned short id = 1;
216 /* search for lowest bridge id that is not in use and not 0 */
222 if (call->bridge_id == id)
235 * receive bchannel data
237 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
241 void rx_dtmf(struct bchannel *bchannel, char tone)
246 * enque message to LCR
248 int send_message(int message_type, unsigned long ref, union parameter *param)
250 struct admin_list *admin, **adminp;
252 adminp = &admin_first;
254 adminp = &((*adminp)->next);
255 admin = (struct admin_list *)malloc(sizeof(struct admin_list));
258 admin->msg.type = message_type;
259 admin->msg.ref = ref;
260 memcpy(&admin->msg.param, param, sizeof(union parameter));
266 * incoming setup from LCR
268 static void lcr_in_setup(struct chan_call *call, int message_type, union parameter *param)
270 struct ast_channel *ast;
271 union parameter newparam;
273 /* create asterisk channel instrance */
274 ast = ast_channel_alloc(1);
278 memset(&newparam, 0, sizeof(union parameter));
279 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
280 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
281 send_message(MESSAGE_RELEASE, call->ref, &newparam);
286 /* set ast pointer */
289 /* fill setup information */
290 #warning todo: setup-info reinschreiben
292 /* send setup to asterisk */
293 #warning todo: setup bei der asterisk triggern
296 call->state = CHAN_LCR_STATE_IN_SETUP;
300 * incoming setup acknowledge from LCR
302 static void lcr_in_overlap(struct chan_call *call, int message_type, union parameter *param)
304 /* send pending digits in dialque */
306 send_dialing_to_lcr(call);
307 /* change to overlap state */
308 call->state = CHAN_LCR_STATE_OUT_DIALING;
312 * incoming proceeding from LCR
314 static void lcr_in_proceeding(struct chan_call *call, int message_type, union parameter *param)
317 call->state = CHAN_LCR_STATE_OUT_PROCEEDING;
318 /* send event to asterisk */
323 * incoming alerting from LCR
325 static void lcr_in_alerting(struct chan_call *call, int message_type, union parameter *param)
328 call->state = CHAN_LCR_STATE_OUT_ALERTING;
329 /* send event to asterisk */
334 * incoming connect from LCR
336 static void lcr_in_connect(struct chan_call *call, int message_type, union parameter *param)
339 call->state = CHAN_LCR_STATE_CONNECT;
340 /* copy connectinfo */
342 /* send event to asterisk */
347 * incoming disconnect from LCR
349 static void lcr_in_disconnect(struct chan_call *call, int message_type, union parameter *param)
352 call->state = CHAN_LCR_STATE_IN_DISCONNECT;
353 /* copy disconnect info */
355 /* send event to asterisk */
360 * incoming setup acknowledge from LCR
362 static void lcr_in_release(struct chan_call *call, int message_type, union parameter *param)
366 /* change to release state */
367 call->state = CHAN_LCR_STATE_RELEASE;
368 /* copy release info */
370 /* if we have an asterisk instance, send hangup, else we are done */
373 ast_queue_hangup(call->ast);
382 * incoming information from LCR
384 static void lcr_in_information(struct chan_call *call, int message_type, union parameter *param)
387 todo and write them, maybe queue them for asterisk
388 /* send event to asterisk */
393 * incoming information from LCR
395 static void lcr_in_facility(struct chan_call *call, int message_type, union parameter *param)
397 /* copy progress info */
398 todo and write them, maybe queue them for asterisk
399 /* send event to asterisk */
401 or maybe use bride info to forward facility.
405 * message received from LCR
407 int receive_message(int message_type, unsigned long ref, union parameter *param)
409 union parameter newparam;
410 struct bchannel *bchannel;
411 struct chan_call *call;
413 memset(&newparam, 0, sizeof(union parameter));
415 /* handle bchannel message*/
416 if (message_type == MESSAGE_BCHANNEL)
418 switch(param->bchannel.type)
420 case BCHANNEL_ASSIGN:
421 if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
423 fprintf(stderr, "error: bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
426 /* create bchannel */
427 bchannel = alloc_bchannel(param->bchannel.handle);
430 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
434 /* configure channel */
435 bchannel->b_tx_gain = param->bchannel.tx_gain;
436 bchannel->b_rx_gain = param->bchannel.rx_gain;
437 strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
438 if (param->bchannel.crypt_len)
440 bchannel->b_crypt_len = param->bchannel.crypt_len;
441 bchannel->b_crypt_type = param->bchannel.crypt_type;
442 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
444 bchannel->b_txdata = 0;
445 bchannel->b_dtmf = 1;
446 bchannel->b_tx_dejitter = 1;
448 /* in case, ref is not set, this bchannel instance must
449 * be created until it is removed again by LCR */
451 if ((call = find_call_ref(ref)))
454 call->bchannel_handle = param->bchannel.handle;
455 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
456 bchannel_join(bchannel, call->bridge_id);
458 if (bchannel_create(bchannel))
459 bchannel_activate(bchannel, 1);
462 newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
463 newparam.bchannel.handle = param->bchannel.handle;
464 send_message(MESSAGE_BCHANNEL, 0, &newparam);
467 case BCHANNEL_REMOVE:
468 if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
470 #warning alle fprintf nach ast_log
471 fprintf(stderr, "error: bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
474 /* unlink from call */
475 if ((call = find_call_ref(bchannel->ref)))
477 call->bchannel_handle = 0;
479 /* destroy and remove bchannel */
480 free_bchannel(bchannel);
483 newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
484 newparam.bchannel.handle = param->bchannel.handle;
485 send_message(MESSAGE_BCHANNEL, 0, &newparam);
490 fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
496 if (message_type == MESSAGE_NEWREF)
498 if (param->direction)
500 /* new ref from lcr */
501 if (!ref || find_call_ref(ref))
503 fprintf(stderr, "illegal new ref %d received\n", ref);
506 /* allocate new call instance */
509 call->state = CHAN_LCR_STATE_IN_PREPARE;
512 /* wait for setup (or release from asterisk) */
515 /* new ref, as requested from this remote application */
516 call = find_call_ref(0);
519 /* send release, if ref does not exist */
520 newparam.disconnectinfo.cause = CAUSE_NORMAL;
521 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
522 send_message(MESSAGE_RELEASE, ref, &newparam);
527 /* send pending setup info */
528 if (call->state == CHAN_LCR_STATE_OUT_PREPARE)
529 send_setup_to_lcr(call);
530 /* release if asterisk has signed off */
531 else if (call->state == CHAN_LCR_STATE_RELEASE)
534 newparam.disconnectinfo.cause = todo
535 newparam.disconnectinfo.location = todo
536 send_message(MESSAGE_RELEASE, ref, &newparam);
548 fprintf(stderr, "received message %d without ref\n", message_type);
551 call = find_call_ref(ref);
554 /* ignore ref that is not used (anymore) */
558 /* handle messages */
562 lcr_in_setup(call, message_type, param);
565 case MESSAGE_OVERLAP:
566 lcr_in_overlap(call, message_type, param);
569 case MESSAGE_PROCEEDING:
570 lcr_in_proceeding(call, message_type, param);
573 case MESSAGE_ALERTING:
574 lcr_in_alerting(call, message_type, param);
577 case MESSAGE_CONNECT:
578 lcr_in_connect(call, message_type, param);
581 case MESSAGE_DISCONNECT:
582 lcr_in_disconnect(call, message_type, param);
585 case MESSAGE_RELEASE:
586 lcr_in_release(call, message_type, param);
589 case MESSAGE_INFORMATION:
590 lcr_in_disconnect(call, message_type, param);
593 case MESSAGE_FACILITY:
594 lcr_in_disconnect(call, message_type, param);
597 case MESSAGE_PATTERN:
601 case MESSAGE_NOPATTERN:
605 case MESSAGE_AUDIOPATH:
617 * warning! not thread safe
618 * returns -1 for socket error, 0 for no work, 1 for work
620 int handle_socket(void)
624 struct admin_message msg;
625 struct admin_list *admin;
629 #warning SOCKET FEHLT!
630 /* read from socket */
631 len = read(sock, &msg, sizeof(msg));
634 printf("Socket closed\n");
635 return(-1); // socket closed
639 if (len != sizeof(msg))
641 fprintf(stderr, "Socket short read (%d)\n", len);
642 return(-1); // socket error
644 if (msg.message != ADMIN_MESSAGE)
646 fprintf(stderr, "Socket received illegal message %d\n", msg.message);
647 return(-1); // socket error
649 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
650 printf("message received %d\n", msg.u.msg.type);
654 if (errno != EWOULDBLOCK)
656 fprintf(stderr, "Socket error %d\n", errno);
661 /* write to socket */
665 len = write(sock, &admin->msg, sizeof(msg));
668 printf("Socket closed\n");
669 return(-1); // socket closed
673 if (len != sizeof(msg))
675 fprintf(stderr, "Socket short write (%d)\n", len);
676 return(-1); // socket error
679 admin_first = admin->next;
685 if (errno != EWOULDBLOCK)
687 fprintf(stderr, "Socket error %d\n", errno);
696 * open and close socket
698 int open_socket(void)
702 char *socket_name = SOCKET_NAME;
704 struct sockaddr_un sock_address;
705 unsigned long on = 1;
706 union parameter param;
709 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
711 ast_log(LOG_ERROR, "Failed to create socket.\n");
715 /* set socket address and name */
716 memset(&sock_address, 0, sizeof(sock_address));
717 sock_address.sun_family = PF_UNIX;
718 strcpy(sock_address.sun_path, socket_name);
721 if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
724 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
728 /* set non-blocking io */
729 if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
732 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
736 /* enque hello message */
737 memset(¶m, 0, sizeof(param));
738 strcpy(param.hello.application, "asterisk");
739 send_message(MESSAGE_HELLO, 0, ¶m);
744 void close_socket(int sock)
752 socket muss per timer fuer das öffnen checken
753 static void *chan_thread(void *arg)
762 int ret = handle_socket();
769 ret = bchannel_handle();
775 pthread_mutex_unlock(&chan_lock);
777 pthread_mutex_lock(&chan_lock);
784 * send setup info to LCR
785 * this function is called, when asterisk call is received and ref is received
787 static void send_setup_to_lcr(struct chan_call *call)
789 if (!ast || !call->ref)
792 /* send setup message to LCR */
793 memset(&newparam, 0, sizeof(union parameter));
794 newparam.setup.xxxxxx =
795 send_message(MESSAGE_SETUP, call->ref, &newparam);
796 /* change to outgoing setup state */
797 call->state = CHAN_LCR_STATE_OUT_SETUP;
801 CHRISTIAN: das war ein konflikt beim pullen
802 siehe anderes lcr_request();
803 bedenke: das ast_log muss noch üeberall eingepflegt werden
805 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
807 struct chan_call *call=alloc_call();
810 #warning hier muss jetzt wohl eine Ref angefordert werden!
811 ast=lcr_ast_new(call, ext, NULL, 0 );
816 ast_log(LOG_WARNING, "Could not create new Asterisk Channel\n");
820 ast_log(LOG_WARNING, "Could not create new Lcr Call Handle\n");
826 struct ast_channel *ast=NULL;
829 char *port_str, *ext, *p;
832 ast_copy_string(buf, data, sizeof(buf)-1);
834 port_str=strsep(&p, "/");
836 ast_verbose("portstr:%s ext:%s\n",port_str, ext);
838 sprintf(buf,"%s/%s",lcr_type,(char*)data);
842 * send dialing info to LCR
843 * this function is called, when setup acknowledge is received and dialing
846 static void send_dialing_to_lcr(struct chan_call *call)
848 if (!ast || !call->ref || !call->dialque)
851 /* send setup message to LCR */
852 memset(&newparam, 0, sizeof(union parameter));
853 strncpy(newparam.dialinginfo.id, call->dialque, sizeof(newparam.dialinginfo.id)-1);
854 call->dialque[0] = '\0';
855 send_message(MESSAGE_INFORMATION, call->ref, &newparam);
859 * new asterisk instance
861 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
863 pthread_mutex_lock(&chan_lock);
865 /* create call instance */
869 /* failed to create instance */
872 /* create asterisk channel instrance */
873 ast = ast_channel_alloc(1);
877 /* failed to create instance */
881 ast->tech_pvt = call;
883 /* send MESSAGE_NEWREF */
884 memset(&newparam, 0, sizeof(union parameter));
885 newparam.direction = 0; /* request from app */
886 send_message(MESSAGE_NEWREF, 0, &newparam);
888 call->state = CHAN_LCR_STATE_OUT_PREPARE;
890 pthread_mutex_unlock(&chan_lock);
896 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
898 struct chan_call *call=ast->tech_pvt;
900 char *port_str, *dad, *p;
902 if (!call) return -1;
904 pthread_mutex_lock(&chan_lock);
907 ast_copy_string(buf, dest, sizeof(buf)-1);
909 port_str=strsep(&p, "/");
912 /* send setup message, if we already have a callref */
914 send_setup_to_lcr(call);
917 ast_verbose("Call: ext:%s dest:(%s) -> dad(%s) \n", ast->exten,dest, dad);
919 #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.
921 pthread_mutex_unlock(&chan_lock);
925 static int lcr_digit(struct ast_channel *ast, char digit)
929 if (!call) return -1;
931 /* only pass IA5 number space */
932 if (digit > 126 || digit < 32)
935 pthread_mutex_lock(&chan_lock);
937 /* send information or queue them */
938 if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING)
940 send_dialing_to_lcr(call);
943 && (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP));
946 strncat(call->dialque, buf, strlen(char->dialque)-1);
949 digits kommen, koennen aber nicht verwendet werden.
950 sollen wir sie als info senden (im connect zb.)
953 pthread_mutex_unlock(&chan_lock);
958 static int lcr_answer(struct ast_channel *c)
960 struct chan_call *call=c->tech_pvt;
961 if (!call) return -1;
962 pthread_mutex_lock(&chan_lock);
963 pthread_mutex_unlock(&chan_lock);
967 static int lcr_hangup(struct ast_channel *ast)
969 struct chan_call *call = ast->tech_pvt;
974 pthread_mutex_lock(&chan_lock);
975 /* disconnect asterisk, maybe not required */
976 ast->tech_pvt = NULL;
980 memset(&newparam, 0, sizeof(union parameter));
981 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
982 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
983 send_message(MESSAGE_RELEASE, call->ref, &newparam);
986 pthread_mutex_unlock(&chan_lock);
990 /* ref is not set, due to prepare setup or release */
991 if (call->state == CHAN_LCR_STATE_RELEASE)
993 /* we get the response to our release */
997 /* during prepare, we change to release state */
998 call->state = CHAN_LCR_STATE_RELEASE;
1001 pthread_mutex_unlock(&chan_lock);
1005 static int lcr_write(struct ast_channel *c, struct ast_frame *f)
1007 struct chan_call *call= c->tech_pvt;
1008 if (!call) return 0;
1009 pthread_mutex_lock(&chan_lock);
1010 pthread_mutex_unlock(&chan_lock);
1014 static struct ast_frame *lcr_read(struct ast_channel *c)
1016 struct chan_call *call = c->tech_pvt;
1017 if (!call) return 0;
1018 pthread_mutex_lock(&chan_lock);
1019 pthread_mutex_unlock(&chan_lock);
1022 static int lcr_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
1025 if (!call) return -1;
1027 pthread_mutex_lock(&chan_lock);
1030 case AST_CONTROL_BUSY:
1031 case AST_CONTROL_CONGESTION:
1032 case AST_CONTROL_RINGING:
1033 pthread_mutex_unlock(&chan_lock);
1036 pthread_mutex_unlock(&chan_lock);
1039 case AST_CONTROL_VIDUPDATE:
1042 case AST_CONTROL_HOLD:
1043 ast_verbose(" << Console Has Been Placed on Hold >> \n");
1044 //ast_moh_start(c, data, g->mohinterpret);
1046 case AST_CONTROL_UNHOLD:
1047 ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
1052 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
1053 pthread_mutex_unlock(&chan_lock);
1057 pthread_mutex_unlock(&chan_lock);
1061 static struct ast_channel_tech lcr_tech = {
1063 .description="Channel driver for connecting to Linux-Call-Router",
1064 .capabilities=AST_FORMAT_ALAW,
1065 .requester=lcr_request,
1066 .send_digit=lcr_digit,
1068 // .bridge=lcr_bridge,
1073 .indicate=lcr_indicate,
1074 // .fixup=lcr_fixup,
1075 // .send_text=lcr_send_text,
1079 #warning das muss mal aus der config datei gelesen werden:
1080 char lcr_context[]="from-lcr";
1082 static struct ast_channel *lcr_ast_new(struct chan_call *call, char *exten, char *callerid, int ref)
1084 struct ast_channel *tmp;
1085 char *cid_name = 0, *cid_num = 0;
1089 ast_callerid_parse(callerid, &cid_name, &cid_num);
1091 tmp = ast_channel_alloc(1, AST_STATE_RESERVED, cid_num, cid_name, "", exten, "", 0, "%s/%d", lcr_type, ref);
1094 tmp->tech = &lcr_tech;
1095 tmp->writeformat = AST_FORMAT_ALAW;
1096 tmp->readformat = AST_FORMAT_ALAW;
1098 ast_copy_string(tmp->context, lcr_context, AST_MAX_CONTEXT);
1110 static int lcr_show_lcr (int fd, int argc, char *argv[])
1114 static int lcr_show_calls (int fd, int argc, char *argv[])
1118 static int lcr_reload_routing (int fd, int argc, char *argv[])
1122 static int lcr_reload_interfaces (int fd, int argc, char *argv[])
1126 static int lcr_port_block (int fd, int argc, char *argv[])
1130 static int lcr_port_unblock (int fd, int argc, char *argv[])
1134 static int lcr_port_unload (int fd, int argc, char *argv[])
1138 static struct ast_cli_entry cli_show_lcr =
1139 { {"lcr", "show", "lcr", NULL},
1141 "Shows current states of LCR core",
1142 "Usage: lcr show lcr\n",
1145 static struct ast_cli_entry cli_show_calls =
1146 { {"lcr", "show", "calls", NULL},
1148 "Shows current calls made by LCR and Asterisk",
1149 "Usage: lcr show calls\n",
1152 static struct ast_cli_entry cli_reload_routing =
1153 { {"lcr", "reload", "routing", NULL},
1155 "Reloads routing conf of LCR, current uncomplete calls will be disconnected",
1156 "Usage: lcr reload routing\n",
1159 static struct ast_cli_entry cli_reload_interfaces =
1160 { {"lcr", "reload", "interfaces", NULL},
1161 lcr_reload_interfaces,
1162 "Reloads interfaces conf of LCR",
1163 "Usage: lcr reload interfaces\n",
1166 static struct ast_cli_entry cli_port_block =
1167 { {"lcr", "port", "block", NULL},
1169 "Blocks LCR port for further calls",
1170 "Usage: lcr port block \"<port>\"\n",
1173 static struct ast_cli_entry cli_port_unblock =
1174 { {"lcr", "port", "unblock", NULL},
1176 "Unblocks or loads LCR port, port is opened my mISDN",
1177 "Usage: lcr port unblock \"<port>\"\n",
1180 static struct ast_cli_entry cli_port_unload =
1181 { {"lcr", "port", "unload", NULL},
1183 "Unloads LCR port, port is closes by mISDN",
1184 "Usage: lcr port unload \"<port>\"\n",
1189 * module loading and destruction
1191 int load_module(void)
1193 // ast_mutex_init(&release_lock);
1195 // lcr_cfg_update_ptp();
1197 pthread_mutex_init(&chan_lock, NULL);
1199 if (!(lcr_sock = open_socket())) {
1200 ast_log(LOG_ERROR, "Unable to connect\n");
1202 /* continue with closed socket */
1205 if (!bchannel_initialize()) {
1206 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
1211 if (ast_channel_register(&lcr_tech)) {
1212 ast_log(LOG_ERROR, "Unable to register channel class\n");
1217 ast_cli_register(&cli_show_lcr);
1218 ast_cli_register(&cli_show_calls);
1220 ast_cli_register(&cli_reload_routing);
1221 ast_cli_register(&cli_reload_interfaces);
1222 ast_cli_register(&cli_port_block);
1223 ast_cli_register(&cli_port_unblock);
1224 ast_cli_register(&cli_port_unload);
1226 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
1227 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
1228 "Sets mISDN opts. and optargs\n"
1230 "The available options are:\n"
1231 " d - Send display text on called phone, text is the optparam\n"
1232 " n - don't detect dtmf tones on called channel\n"
1233 " h - make digital outgoing call\n"
1234 " c - make crypted outgoing call, param is keyindex\n"
1235 " e - perform echo cancelation on this channel,\n"
1236 " takes taps as arguments (32,64,128,256)\n"
1237 " s - send Non Inband DTMF as inband\n"
1238 " vr - rxgain control\n"
1239 " vt - txgain control\n"
1243 lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1245 chan_lcr_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
1247 //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1251 if ((pthread_create(&chan_tid, NULL, chan_thread, arg)<0))
1253 failed to create thread
1259 int unload_module(void)
1261 /* First, take us out of the channel loop */
1262 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
1265 pthread_join(chan_tid, NULL);
1267 ast_channel_unregister(&lcr_tech);
1269 if (mISDN_created) {
1270 bchannel_deinitialize();
1274 if (lcr_sock >= 0) {
1282 static int reload_module(void)
1289 ast_mutex_t usecnt_lock;
1295 ast_mutex_lock(&usecnt_lock);
1297 ast_mutex_unlock(&usecnt_lock);
1302 char *desc="Channel driver for lcr";
1304 char *description(void)
1311 return ASTERISK_GPL_KEY;
1314 #define AST_MODULE "chan_lcr"
1315 AST_MODULE_INFO(ASTERISK_GPL_KEY,
1316 AST_MODFLAG_DEFAULT,
1317 "Channel driver for LCR",
1318 .load = load_module,
1319 .unload = unload_module,
1320 .reload = reload_module,