1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** Asterisk socket client **
10 \*****************************************************************************/
16 To connect, open a socket and send a MESSAGE_HELLO to admin socket with
17 the application name. This name is unique an can be used for routing calls.
19 To make a call, send a MESSAGE_NEWREF and a new reference is received.
20 When receiving a call, a new reference is received.
21 The reference is received with MESSAGE_NEWREF.
23 Make a MESSAGE_SETUP or receive a MESSAGE_SETUP with the reference.
25 To release call and reference, send or receive MESSAGE_RELEASE.
26 From that point on, the ref is not valid, so no other message may be sent
30 bchannel-handling muss noch
37 #include <sys/types.h>
41 #include <sys/ioctl.h>
42 #include <sys/socket.h>
46 #include <semaphore.h>
48 #include "extension.h"
50 #include "lcrsocket.h"
57 #include <asterisk/module.h>
58 #include <asterisk/channel.h>
59 #include <asterisk/config.h>
60 #include <asterisk/logger.h>
61 #include <asterisk/pbx.h>
62 #include <asterisk/options.h>
63 #include <asterisk/io.h>
64 #include <asterisk/frame.h>
65 #include <asterisk/translate.h>
66 #include <asterisk/cli.h>
67 #include <asterisk/musiconhold.h>
68 #include <asterisk/dsp.h>
69 #include <asterisk/translate.h>
70 #include <asterisk/file.h>
71 #include <asterisk/callerid.h>
72 #include <asterisk/indications.h>
73 #include <asterisk/app.h>
74 #include <asterisk/features.h>
75 #include <asterisk/sched.h>
84 struct admin_list *next;
86 } *admin_first = NULL;
89 * channel and call instances
91 struct chan_call *call_first;
93 struct chan_call *find_call_ref(unsigned long ref)
95 struct chan_call *call = call_first;
106 struct chan_call *find_call_handle(unsigned long handle)
108 struct chan_call *call = call_first;
112 if (call->bchannel_handle == handle)
119 struct chan_call *alloc_call(void)
121 struct chan_call **callp = &call_first;
124 callp = &((*callp)->next);
126 *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
130 void free_call(struct chan_call *call)
132 struct chan_call **temp = &call_first;
138 *temp = (*temp)->next;
142 temp = &((*temp)->next);
146 unsigned short new_brige_id(void)
148 struct chan_call *call;
149 unsigned short id = 1;
151 /* search for lowest bridge id that is not in use and not 0 */
157 if (call->bridge_id == id)
170 * receive bchannel data
172 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
176 void rx_dtmf(struct bchannel *bchannel, char tone)
181 * enque message to LCR
183 int send_message(int message_type, unsigned long ref, union parameter *param)
185 struct admin_list *admin, **adminp;
187 adminp = &admin_first;
189 adminp = &((*adminp)->next);
190 admin = (struct admin_list *)malloc(sizeof(struct admin_list));
193 admin->msg.type = message_type;
194 admin->msg.ref = ref;
195 memcpy(&admin->msg.param, param, sizeof(union parameter));
201 * message received from LCR
203 int receive_message(int message_type, unsigned long ref, union parameter *param)
205 union parameter newparam;
206 struct bchannel *bchannel;
207 struct chan_call *call;
209 memset(&newparam, 0, sizeof(union parameter));
211 /* handle bchannel message*/
212 if (message_type == MESSAGE_BCHANNEL)
214 switch(param->bchannel.type)
216 case BCHANNEL_ASSIGN:
217 if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
219 fprintf(stderr, "error: bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
222 /* create bchannel */
223 bchannel = alloc_bchannel(param->bchannel.handle);
226 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
230 /* configure channel */
231 bchannel->b_tx_gain = param->bchannel.tx_gain;
232 bchannel->b_rx_gain = param->bchannel.rx_gain;
233 strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
234 if (param->bchannel.crypt_len)
236 bchannel->b_crypt_len = param->bchannel.crypt_len;
237 bchannel->b_crypt_type = param->bchannel.crypt_type;
238 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
240 bchannel->b_txdata = 0;
241 bchannel->b_dtmf = 1;
242 bchannel->b_tx_dejitter = 1;
244 /* in case, ref is not set, this bchannel instance must
245 * be created until it is removed again by LCR */
247 if ((call = find_call_ref(ref)))
250 call->bchannel_handle = param->bchannel.handle;
251 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
252 bchannel_join(bchannel, call->bridge_id);
254 if (bchannel_create(bchannel))
255 bchannel_activate(bchannel, 1);
258 newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
259 newparam.bchannel.handle = param->bchannel.handle;
260 send_message(MESSAGE_BCHANNEL, 0, &newparam);
263 case BCHANNEL_REMOVE:
264 if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
266 #warning alle fprintf nach ast_log
267 fprintf(stderr, "error: bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
270 /* unlink from call */
271 if ((call = find_call_ref(bchannel->ref)))
273 call->bchannel_handle = 0;
275 /* destroy and remove bchannel */
276 free_bchannel(bchannel);
279 newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
280 newparam.bchannel.handle = param->bchannel.handle;
281 send_message(MESSAGE_BCHANNEL, 0, &newparam);
286 fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
292 if (message_type == MESSAGE_NEWREF)
294 if (param->direction)
296 /* new ref from lcr */
297 if (!ref || find_call_ref(ref))
299 fprintf(stderr, "illegal new ref %d received\n", ref);
306 /* new ref, as requested from this remote application */
307 call = find_call_ref(0);
310 /* send release, if ref does not exist */
311 newparam.disconnectinfo.cause = CAUSE_NORMAL;
312 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
313 send_message(MESSAGE_RELEASE, ref, &newparam);
317 #warning process call (send setup, if pending)
325 fprintf(stderr, "received message %d without ref\n", message_type);
328 call = find_call_ref(ref);
331 /* ignore ref that is not used (anymore) */
335 /* handle messages */
342 case MESSAGE_OVERLAP:
346 case MESSAGE_PROCEEDING:
350 case MESSAGE_ALERTING:
354 case MESSAGE_CONNECT:
358 case MESSAGE_DISCONNECT:
362 case MESSAGE_RELEASE:
367 case MESSAGE_INFORMATION:
371 case MESSAGE_FACILITY:
375 case MESSAGE_PATTERN:
379 case MESSAGE_NOPATTERN:
383 case MESSAGE_AUDIOPATH:
395 * warning! not thread safe
396 * returns -1 for socket error, 0 for no work, 1 for work
398 int handle_socket(void)
402 struct admin_message msg;
403 struct admin_list *admin;
407 #warning SOCKET FEHLT!
408 /* read from socket */
409 len = read(sock, &msg, sizeof(msg));
412 printf("Socket closed\n");
413 return(-1); // socket closed
417 if (len != sizeof(msg))
419 fprintf(stderr, "Socket short read (%d)\n", len);
420 return(-1); // socket error
422 if (msg.message != ADMIN_MESSAGE)
424 fprintf(stderr, "Socket received illegal message %d\n", msg.message);
425 return(-1); // socket error
427 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
428 printf("message received %d\n", msg.u.msg.type);
432 if (errno != EWOULDBLOCK)
434 fprintf(stderr, "Socket error %d\n", errno);
439 /* write to socket */
443 len = write(sock, &admin->msg, sizeof(msg));
446 printf("Socket closed\n");
447 return(-1); // socket closed
451 if (len != sizeof(msg))
453 fprintf(stderr, "Socket short write (%d)\n", len);
454 return(-1); // socket error
457 admin_first = admin->next;
463 if (errno != EWOULDBLOCK)
465 fprintf(stderr, "Socket error %d\n", errno);
474 * open and close socket
476 int open_socket(void)
480 char *socket_name = SOCKET_NAME;
482 struct sockaddr_un sock_address;
483 unsigned long on = 1;
484 union parameter param;
487 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
489 ast_log(LOG_ERROR, "Failed to create socket.\n");
493 /* set socket address and name */
494 memset(&sock_address, 0, sizeof(sock_address));
495 sock_address.sun_family = PF_UNIX;
496 strcpy(sock_address.sun_path, socket_name);
499 if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
502 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
506 /* set non-blocking io */
507 if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
510 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
514 /* enque hello message */
515 memset(¶m, 0, sizeof(param));
516 strcpy(param.hello.application, "asterisk");
517 send_message(MESSAGE_HELLO, 0, ¶m);
522 void close_socket(int sock)
530 void lcr_thread(void)
539 int ret = handle_socket();
546 ret = bchannel_handle();
555 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
561 /* call from asterisk (new instance) */
562 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
564 struct lcr_pvt *lcr=ast->tech_pvt;
569 char *port_str, *dad, *p;
571 ast_copy_string(buf, dest, sizeof(buf)-1);
573 port_str=strsep(&p, "/");
577 ast_verbose("Call: ext:%s dest:(%s) -> dad(%s) \n", ast->exten,dest, dad);
583 static int lcr_answer(struct ast_channel *c)
585 struct lcr_pvt *lcr=c->tech_pvt;
589 static int lcr_hangup(struct ast_channel *c)
591 struct lcr_pvt *lcr=c->tech_pvt;
596 static int lcr_write(struct ast_channel *c, struct ast_frame *f)
598 struct lcr_pvt *lcrm= c->tech_pvt;
602 static struct ast_frame *lcr_read(struct ast_channel *c)
604 struct lcr_pvt *lcr = c->tech_pvt;
607 static int lcr_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
612 case AST_CONTROL_BUSY:
613 case AST_CONTROL_CONGESTION:
614 case AST_CONTROL_RINGING:
619 case AST_CONTROL_VIDUPDATE:
622 case AST_CONTROL_HOLD:
623 ast_verbose(" << Console Has Been Placed on Hold >> \n");
624 //ast_moh_start(c, data, g->mohinterpret);
626 case AST_CONTROL_UNHOLD:
627 ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
632 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
639 static struct ast_channel_tech lcr_tech = {
641 .description="Channel driver for connecting to Linux-Call-Router",
642 .capabilities=AST_FORMAT_ALAW,
643 .requester=lcr_request,
644 // .send_digit=lcr_digit,
646 // .bridge=lcr_bridge,
651 .indicate=lcr_indicate,
653 // .send_text=lcr_send_text,
659 * module loading and destruction
661 int load_module(void)
663 // ast_mutex_init(&release_lock);
665 // lcr_cfg_update_ptp();
667 if (!(lcr_sock = open_socket())) {
668 ast_log(LOG_ERROR, "Unable to connect\n");
670 /* continue with closed socket */
673 if (!bchannel_initialize()) {
674 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
679 if (ast_channel_register(&lcr_tech)) {
680 ast_log(LOG_ERROR, "Unable to register channel class\n");
684 //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
689 int unload_module(void)
691 /* First, take us out of the channel loop */
692 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
695 ast_channel_unregister(&lcr_tech);
698 bchannel_deinitialize();
710 static int reload_module(void)
717 ast_mutex_t usecnt_lock;
723 ast_mutex_lock(&usecnt_lock);
725 ast_mutex_unlock(&usecnt_lock);
730 char *desc="Channel driver for lcr";
732 char *description(void)
739 return ASTERISK_GPL_KEY;
742 #define AST_MODULE "chan_lcr"
743 AST_MODULE_INFO(ASTERISK_GPL_KEY,
745 "Channel driver for lcr",
747 .unload = unload_module,
748 .reload = reload_module,