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";
140 pthread_mutex_t chan_lock;
145 struct admin_list *next;
146 struct admin_msg msg;
147 } *admin_first = NULL;
150 * channel and call instances
152 struct chan_call *call_first;
154 struct chan_call *find_call_ref(unsigned long ref)
156 struct chan_call *call = call_first;
160 if (call->ref == ref)
167 struct chan_call *find_call_handle(unsigned long handle)
169 struct chan_call *call = call_first;
173 if (call->bchannel_handle == handle)
180 struct chan_call *alloc_call(void)
182 struct chan_call **callp = &call_first;
185 callp = &((*callp)->next);
187 *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
189 memset(*callp, 0, sizeof(struct chan_call));
193 void free_call(struct chan_call *call)
195 struct chan_call **temp = &call_first;
201 *temp = (*temp)->next;
205 temp = &((*temp)->next);
209 unsigned short new_brige_id(void)
211 struct chan_call *call;
212 unsigned short id = 1;
214 /* search for lowest bridge id that is not in use and not 0 */
220 if (call->bridge_id == id)
233 * receive bchannel data
235 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
239 void rx_dtmf(struct bchannel *bchannel, char tone)
244 * enque message to LCR
246 int send_message(int message_type, unsigned long ref, union parameter *param)
248 struct admin_list *admin, **adminp;
250 adminp = &admin_first;
252 adminp = &((*adminp)->next);
253 admin = (struct admin_list *)malloc(sizeof(struct admin_list));
256 admin->msg.type = message_type;
257 admin->msg.ref = ref;
258 memcpy(&admin->msg.param, param, sizeof(union parameter));
264 * incoming setup from LCR
266 static void lcr_in_setup(struct chan_call *call, int message_type, union parameter *param)
268 struct ast_channel *ast;
269 union parameter newparam;
271 /* create asterisk channel instrance */
272 ast = ast_channel_alloc(1);
276 memset(&newparam, 0, sizeof(union parameter));
277 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
278 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
279 send_message(MESSAGE_RELEASE, call->ref, &newparam);
284 /* set ast pointer */
287 /* fill setup information */
288 #warning todo: setup-info reinschreiben
290 /* send setup to asterisk */
291 #warning todo: setup bei der asterisk triggern
294 call->state = CHAN_LCR_STATE_IN_SETUP;
298 * incoming setup acknowledge from LCR
300 static void lcr_in_overlap(struct chan_call *call, int message_type, union parameter *param)
302 /* send pending digits in dialque */
304 send_dialing_to_lcr(call);
305 /* change to overlap state */
306 call->state = CHAN_LCR_STATE_OUT_DIALING;
310 * incoming proceeding from LCR
312 static void lcr_in_proceeding(struct chan_call *call, int message_type, union parameter *param)
315 call->state = CHAN_LCR_STATE_OUT_PROCEEDING;
316 /* send event to asterisk */
321 * incoming alerting from LCR
323 static void lcr_in_alerting(struct chan_call *call, int message_type, union parameter *param)
326 call->state = CHAN_LCR_STATE_OUT_ALERTING;
327 /* send event to asterisk */
332 * incoming connect from LCR
334 static void lcr_in_connect(struct chan_call *call, int message_type, union parameter *param)
337 call->state = CHAN_LCR_STATE_CONNECT;
338 /* copy connectinfo */
340 /* send event to asterisk */
345 * incoming disconnect from LCR
347 static void lcr_in_disconnect(struct chan_call *call, int message_type, union parameter *param)
350 call->state = CHAN_LCR_STATE_IN_DISCONNECT;
351 /* copy disconnect info */
353 /* send event to asterisk */
358 * incoming setup acknowledge from LCR
360 static void lcr_in_release(struct chan_call *call, int message_type, union parameter *param)
364 /* change to release state */
365 call->state = CHAN_LCR_STATE_RELEASE;
366 /* copy release info */
368 /* if we have an asterisk instance, send hangup, else we are done */
371 ast_queue_hangup(call->ast);
380 * incoming information from LCR
382 static void lcr_in_information(struct chan_call *call, int message_type, union parameter *param)
385 todo and write them, maybe queue them for asterisk
386 /* send event to asterisk */
391 * incoming information from LCR
393 static void lcr_in_facility(struct chan_call *call, int message_type, union parameter *param)
395 /* copy progress info */
396 todo and write them, maybe queue them for asterisk
397 /* send event to asterisk */
399 or maybe use bride info to forward facility.
403 * message received from LCR
405 int receive_message(int message_type, unsigned long ref, union parameter *param)
407 union parameter newparam;
408 struct bchannel *bchannel;
409 struct chan_call *call;
411 memset(&newparam, 0, sizeof(union parameter));
413 /* handle bchannel message*/
414 if (message_type == MESSAGE_BCHANNEL)
416 switch(param->bchannel.type)
418 case BCHANNEL_ASSIGN:
419 if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
421 fprintf(stderr, "error: bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
424 /* create bchannel */
425 bchannel = alloc_bchannel(param->bchannel.handle);
428 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
432 /* configure channel */
433 bchannel->b_tx_gain = param->bchannel.tx_gain;
434 bchannel->b_rx_gain = param->bchannel.rx_gain;
435 strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
436 if (param->bchannel.crypt_len)
438 bchannel->b_crypt_len = param->bchannel.crypt_len;
439 bchannel->b_crypt_type = param->bchannel.crypt_type;
440 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
442 bchannel->b_txdata = 0;
443 bchannel->b_dtmf = 1;
444 bchannel->b_tx_dejitter = 1;
446 /* in case, ref is not set, this bchannel instance must
447 * be created until it is removed again by LCR */
449 if ((call = find_call_ref(ref)))
452 call->bchannel_handle = param->bchannel.handle;
453 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
454 bchannel_join(bchannel, call->bridge_id);
456 if (bchannel_create(bchannel))
457 bchannel_activate(bchannel, 1);
460 newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
461 newparam.bchannel.handle = param->bchannel.handle;
462 send_message(MESSAGE_BCHANNEL, 0, &newparam);
465 case BCHANNEL_REMOVE:
466 if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
468 #warning alle fprintf nach ast_log
469 fprintf(stderr, "error: bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
472 /* unlink from call */
473 if ((call = find_call_ref(bchannel->ref)))
475 call->bchannel_handle = 0;
477 /* destroy and remove bchannel */
478 free_bchannel(bchannel);
481 newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
482 newparam.bchannel.handle = param->bchannel.handle;
483 send_message(MESSAGE_BCHANNEL, 0, &newparam);
488 fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
494 if (message_type == MESSAGE_NEWREF)
496 if (param->direction)
498 /* new ref from lcr */
499 if (!ref || find_call_ref(ref))
501 fprintf(stderr, "illegal new ref %d received\n", ref);
504 /* allocate new call instance */
507 call->state = CHAN_LCR_STATE_IN_PREPARE;
510 /* wait for setup (or release from asterisk) */
513 /* new ref, as requested from this remote application */
514 call = find_call_ref(0);
517 /* send release, if ref does not exist */
518 newparam.disconnectinfo.cause = CAUSE_NORMAL;
519 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
520 send_message(MESSAGE_RELEASE, ref, &newparam);
525 /* send pending setup info */
526 if (call->state == CHAN_LCR_STATE_OUT_PREPARE)
527 send_setup_to_lcr(call);
528 /* release if asterisk has signed off */
529 else if (call->state == CHAN_LCR_STATE_RELEASE)
532 newparam.disconnectinfo.cause = todo
533 newparam.disconnectinfo.location = todo
534 send_message(MESSAGE_RELEASE, ref, &newparam);
546 fprintf(stderr, "received message %d without ref\n", message_type);
549 call = find_call_ref(ref);
552 /* ignore ref that is not used (anymore) */
556 /* handle messages */
560 lcr_in_setup(call, message_type, param);
563 case MESSAGE_OVERLAP:
564 lcr_in_overlap(call, message_type, param);
567 case MESSAGE_PROCEEDING:
568 lcr_in_proceeding(call, message_type, param);
571 case MESSAGE_ALERTING:
572 lcr_in_alerting(call, message_type, param);
575 case MESSAGE_CONNECT:
576 lcr_in_connect(call, message_type, param);
579 case MESSAGE_DISCONNECT:
580 lcr_in_disconnect(call, message_type, param);
583 case MESSAGE_RELEASE:
584 lcr_in_release(call, message_type, param);
587 case MESSAGE_INFORMATION:
588 lcr_in_disconnect(call, message_type, param);
591 case MESSAGE_FACILITY:
592 lcr_in_disconnect(call, message_type, param);
595 case MESSAGE_PATTERN:
599 case MESSAGE_NOPATTERN:
603 case MESSAGE_AUDIOPATH:
615 * warning! not thread safe
616 * returns -1 for socket error, 0 for no work, 1 for work
618 int handle_socket(void)
622 struct admin_message msg;
623 struct admin_list *admin;
627 #warning SOCKET FEHLT!
628 /* read from socket */
629 len = read(sock, &msg, sizeof(msg));
632 printf("Socket closed\n");
633 return(-1); // socket closed
637 if (len != sizeof(msg))
639 fprintf(stderr, "Socket short read (%d)\n", len);
640 return(-1); // socket error
642 if (msg.message != ADMIN_MESSAGE)
644 fprintf(stderr, "Socket received illegal message %d\n", msg.message);
645 return(-1); // socket error
647 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
648 printf("message received %d\n", msg.u.msg.type);
652 if (errno != EWOULDBLOCK)
654 fprintf(stderr, "Socket error %d\n", errno);
659 /* write to socket */
663 len = write(sock, &admin->msg, sizeof(msg));
666 printf("Socket closed\n");
667 return(-1); // socket closed
671 if (len != sizeof(msg))
673 fprintf(stderr, "Socket short write (%d)\n", len);
674 return(-1); // socket error
677 admin_first = admin->next;
683 if (errno != EWOULDBLOCK)
685 fprintf(stderr, "Socket error %d\n", errno);
694 * open and close socket
696 int open_socket(void)
700 char *socket_name = SOCKET_NAME;
702 struct sockaddr_un sock_address;
703 unsigned long on = 1;
704 union parameter param;
707 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
709 ast_log(LOG_ERROR, "Failed to create socket.\n");
713 /* set socket address and name */
714 memset(&sock_address, 0, sizeof(sock_address));
715 sock_address.sun_family = PF_UNIX;
716 strcpy(sock_address.sun_path, socket_name);
719 if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
722 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
726 /* set non-blocking io */
727 if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
730 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
734 /* enque hello message */
735 memset(¶m, 0, sizeof(param));
736 strcpy(param.hello.application, "asterisk");
737 send_message(MESSAGE_HELLO, 0, ¶m);
742 void close_socket(int sock)
750 hander thread muss noch
751 socket muss per timer fuer das öffnen checken
752 void lcr_thread(void)
761 int ret = handle_socket();
768 ret = bchannel_handle();
774 pthread_mutex_unlock(&chan_lock);
776 pthread_mutex_lock(&chan_lock);
782 * send setup info to LCR
783 * this function is called, when asterisk call is received and ref is received
785 static void send_setup_to_lcr(struct chan_call *call)
787 if (!ast || !call->ref)
790 /* send setup message to LCR */
791 memset(&newparam, 0, sizeof(union parameter));
792 newparam.setup.xxxxxx =
793 send_message(MESSAGE_SETUP, call->ref, &newparam);
794 /* change to outgoing setup state */
795 call->state = CHAN_LCR_STATE_OUT_SETUP;
799 CHRISTIAN: das war ein konflikt beim pullen
800 siehe anderes lcr_request();
801 bedenke: das ast_log muss noch üeberall eingepflegt werden
803 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
805 struct chan_call *call=alloc_call();
808 #warning hier muss jetzt wohl eine Ref angefordert werden!
809 ast=lcr_ast_new(call, ext, NULL, 0 );
814 ast_log(LOG_WARNING, "Could not create new Asterisk Channel\n");
818 ast_log(LOG_WARNING, "Could not create new Lcr Call Handle\n");
824 struct ast_channel *ast=NULL;
827 char *port_str, *ext, *p;
830 ast_copy_string(buf, data, sizeof(buf)-1);
832 port_str=strsep(&p, "/");
834 ast_verbose("portstr:%s ext:%s\n",port_str, ext);
836 sprintf(buf,"%s/%s",lcr_type,(char*)data);
840 * send dialing info to LCR
841 * this function is called, when setup acknowledge is received and dialing
844 static void send_dialing_to_lcr(struct chan_call *call)
846 if (!ast || !call->ref || !call->dialque)
849 /* send setup message to LCR */
850 memset(&newparam, 0, sizeof(union parameter));
851 strncpy(newparam.dialinginfo.id, call->dialque, sizeof(newparam.dialinginfo.id)-1);
852 call->dialque[0] = '\0';
853 send_message(MESSAGE_INFORMATION, call->ref, &newparam);
857 * new asterisk instance
859 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
861 pthread_mutex_lock(&chan_lock);
863 /* create call instance */
867 /* failed to create instance */
870 /* create asterisk channel instrance */
871 ast = ast_channel_alloc(1);
875 /* failed to create instance */
879 ast->tech_pvt = call;
881 /* send MESSAGE_NEWREF */
882 memset(&newparam, 0, sizeof(union parameter));
883 newparam.direction = 0; /* request from app */
884 send_message(MESSAGE_NEWREF, 0, &newparam);
886 call->state = CHAN_LCR_STATE_OUT_PREPARE;
888 pthread_mutex_unlock(&chan_lock);
894 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
896 struct chan_call *call=ast->tech_pvt;
898 char *port_str, *dad, *p;
900 if (!call) return -1;
902 pthread_mutex_lock(&chan_lock);
905 ast_copy_string(buf, dest, sizeof(buf)-1);
907 port_str=strsep(&p, "/");
910 /* send setup message, if we already have a callref */
912 send_setup_to_lcr(call);
915 ast_verbose("Call: ext:%s dest:(%s) -> dad(%s) \n", ast->exten,dest, dad);
917 #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.
919 pthread_mutex_unlock(&chan_lock);
923 static int lcr_digit(struct ast_channel *ast, char digit)
927 if (!call) return -1;
929 /* only pass IA5 number space */
930 if (digit > 126 || digit < 32)
933 pthread_mutex_lock(&chan_lock);
935 /* send information or queue them */
936 if (call->ref && call->state == CHAN_LCR_STATE_OUT_DIALING)
938 send_dialing_to_lcr(call);
941 && (call->state == CHAN_LCR_STATE_OUT_PREPARE || call->state == CHAN_LCR_STATE_OUT_SETUP));
944 strncat(call->dialque, buf, strlen(char->dialque)-1);
947 digits kommen, koennen aber nicht verwendet werden.
948 sollen wir sie als info senden (im connect zb.)
951 pthread_mutex_unlock(&chan_lock);
956 static int lcr_answer(struct ast_channel *c)
958 struct chan_call *call=c->tech_pvt;
959 if (!call) return -1;
960 pthread_mutex_lock(&chan_lock);
961 pthread_mutex_unlock(&chan_lock);
965 static int lcr_hangup(struct ast_channel *ast)
967 struct chan_call *call = ast->tech_pvt;
972 pthread_mutex_lock(&chan_lock);
973 /* disconnect asterisk, maybe not required */
974 ast->tech_pvt = NULL;
978 memset(&newparam, 0, sizeof(union parameter));
979 newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
980 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
981 send_message(MESSAGE_RELEASE, call->ref, &newparam);
984 pthread_mutex_unlock(&chan_lock);
988 /* ref is not set, due to prepare setup or release */
989 if (call->state == CHAN_LCR_STATE_RELEASE)
991 /* we get the response to our release */
995 /* during prepare, we change to release state */
996 call->state = CHAN_LCR_STATE_RELEASE;
999 pthread_mutex_unlock(&chan_lock);
1003 static int lcr_write(struct ast_channel *c, struct ast_frame *f)
1005 struct chan_call *call= c->tech_pvt;
1006 if (!call) return 0;
1007 pthread_mutex_lock(&chan_lock);
1008 pthread_mutex_unlock(&chan_lock);
1012 static struct ast_frame *lcr_read(struct ast_channel *c)
1014 struct chan_call *call = c->tech_pvt;
1015 if (!call) return 0;
1016 pthread_mutex_lock(&chan_lock);
1017 pthread_mutex_unlock(&chan_lock);
1020 static int lcr_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
1023 if (!call) return -1;
1025 pthread_mutex_lock(&chan_lock);
1028 case AST_CONTROL_BUSY:
1029 case AST_CONTROL_CONGESTION:
1030 case AST_CONTROL_RINGING:
1031 pthread_mutex_unlock(&chan_lock);
1034 pthread_mutex_unlock(&chan_lock);
1037 case AST_CONTROL_VIDUPDATE:
1040 case AST_CONTROL_HOLD:
1041 ast_verbose(" << Console Has Been Placed on Hold >> \n");
1042 //ast_moh_start(c, data, g->mohinterpret);
1044 case AST_CONTROL_UNHOLD:
1045 ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
1050 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
1051 pthread_mutex_unlock(&chan_lock);
1055 pthread_mutex_unlock(&chan_lock);
1059 static struct ast_channel_tech lcr_tech = {
1061 .description="Channel driver for connecting to Linux-Call-Router",
1062 .capabilities=AST_FORMAT_ALAW,
1063 .requester=lcr_request,
1064 .send_digit=lcr_digit,
1066 // .bridge=lcr_bridge,
1071 .indicate=lcr_indicate,
1072 // .fixup=lcr_fixup,
1073 // .send_text=lcr_send_text,
1077 #warning das muss mal aus der config datei gelesen werden:
1078 char lcr_context[]="from-lcr";
1080 static struct ast_channel *lcr_ast_new(struct chan_call *call, char *exten, char *callerid, int ref)
1082 struct ast_channel *tmp;
1083 char *cid_name = 0, *cid_num = 0;
1087 ast_callerid_parse(callerid, &cid_name, &cid_num);
1089 tmp = ast_channel_alloc(1, AST_STATE_RESERVED, cid_num, cid_name, "", exten, "", 0, "%s/%d", lcr_type, ref);
1092 tmp->tech = &lcr_tech;
1093 tmp->writeformat = AST_FORMAT_ALAW;
1094 tmp->readformat = AST_FORMAT_ALAW;
1096 ast_copy_string(tmp->context, lcr_context, AST_MAX_CONTEXT);
1108 static int lcr_show_lcr (int fd, int argc, char *argv[])
1112 static int lcr_show_calls (int fd, int argc, char *argv[])
1116 static int lcr_reload_routing (int fd, int argc, char *argv[])
1120 static int lcr_reload_interfaces (int fd, int argc, char *argv[])
1124 static int lcr_port_block (int fd, int argc, char *argv[])
1128 static int lcr_port_unblock (int fd, int argc, char *argv[])
1132 static int lcr_port_unload (int fd, int argc, char *argv[])
1136 static struct ast_cli_entry cli_show_lcr =
1137 { {"lcr", "show", "lcr", NULL},
1139 "Shows current states of LCR core",
1140 "Usage: lcr show lcr\n",
1143 static struct ast_cli_entry cli_show_calls =
1144 { {"lcr", "show", "calls", NULL},
1146 "Shows current calls made by LCR and Asterisk",
1147 "Usage: lcr show calls\n",
1150 static struct ast_cli_entry cli_reload_routing =
1151 { {"lcr", "reload", "routing", NULL},
1153 "Reloads routing conf of LCR, current uncomplete calls will be disconnected",
1154 "Usage: lcr reload routing\n",
1157 static struct ast_cli_entry cli_reload_interfaces =
1158 { {"lcr", "reload", "interfaces", NULL},
1159 lcr_reload_interfaces,
1160 "Reloads interfaces conf of LCR",
1161 "Usage: lcr reload interfaces\n",
1164 static struct ast_cli_entry cli_port_block =
1165 { {"lcr", "port", "block", NULL},
1167 "Blocks LCR port for further calls",
1168 "Usage: lcr port block \"<port>\"\n",
1171 static struct ast_cli_entry cli_port_unblock =
1172 { {"lcr", "port", "unblock", NULL},
1174 "Unblocks or loads LCR port, port is opened my mISDN",
1175 "Usage: lcr port unblock \"<port>\"\n",
1178 static struct ast_cli_entry cli_port_unload =
1179 { {"lcr", "port", "unload", NULL},
1181 "Unloads LCR port, port is closes by mISDN",
1182 "Usage: lcr port unload \"<port>\"\n",
1187 * module loading and destruction
1189 int load_module(void)
1191 // ast_mutex_init(&release_lock);
1193 // lcr_cfg_update_ptp();
1195 pthread_mutex_init(&chan_lock, NULL);
1197 if (!(lcr_sock = open_socket())) {
1198 ast_log(LOG_ERROR, "Unable to connect\n");
1200 /* continue with closed socket */
1203 if (!bchannel_initialize()) {
1204 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
1209 if (ast_channel_register(&lcr_tech)) {
1210 ast_log(LOG_ERROR, "Unable to register channel class\n");
1215 ast_cli_register(&cli_show_lcr);
1216 ast_cli_register(&cli_show_calls);
1218 ast_cli_register(&cli_reload_routing);
1219 ast_cli_register(&cli_reload_interfaces);
1220 ast_cli_register(&cli_port_block);
1221 ast_cli_register(&cli_port_unblock);
1222 ast_cli_register(&cli_port_unload);
1224 ast_register_application("misdn_set_opt", misdn_set_opt_exec, "misdn_set_opt",
1225 "misdn_set_opt(:<opt><optarg>:<opt><optarg>..):\n"
1226 "Sets mISDN opts. and optargs\n"
1228 "The available options are:\n"
1229 " d - Send display text on called phone, text is the optparam\n"
1230 " n - don't detect dtmf tones on called channel\n"
1231 " h - make digital outgoing call\n"
1232 " c - make crypted outgoing call, param is keyindex\n"
1233 " e - perform echo cancelation on this channel,\n"
1234 " takes taps as arguments (32,64,128,256)\n"
1235 " s - send Non Inband DTMF as inband\n"
1236 " vr - rxgain control\n"
1237 " vt - txgain control\n"
1241 lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1243 chan_lcr_log(0, 0, "-- mISDN Channel Driver Registred -- (BE AWARE THIS DRIVER IS EXPERIMENTAL!)\n");
1245 //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
1251 int unload_module(void)
1253 /* First, take us out of the channel loop */
1254 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
1257 ast_channel_unregister(&lcr_tech);
1259 if (mISDN_created) {
1260 bchannel_deinitialize();
1264 if (lcr_sock >= 0) {
1272 static int reload_module(void)
1279 ast_mutex_t usecnt_lock;
1285 ast_mutex_lock(&usecnt_lock);
1287 ast_mutex_unlock(&usecnt_lock);
1292 char *desc="Channel driver for lcr";
1294 char *description(void)
1301 return ASTERISK_GPL_KEY;
1304 #define AST_MODULE "chan_lcr"
1305 AST_MODULE_INFO(ASTERISK_GPL_KEY,
1306 AST_MODFLAG_DEFAULT,
1307 "Channel driver for LCR",
1308 .load = load_module,
1309 .unload = unload_module,
1310 .reload = reload_module,