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
36 #include <sys/types.h>
40 #include <sys/ioctl.h>
41 #include <sys/socket.h>
45 #include <semaphore.h>
47 #include "extension.h"
49 #include "lcrsocket.h"
56 #include <asterisk/module.h>
57 #include <asterisk/channel.h>
58 #include <asterisk/config.h>
59 #include <asterisk/logger.h>
60 #include <asterisk/pbx.h>
61 #include <asterisk/options.h>
62 #include <asterisk/io.h>
63 #include <asterisk/frame.h>
64 #include <asterisk/translate.h>
65 #include <asterisk/cli.h>
66 #include <asterisk/musiconhold.h>
67 #include <asterisk/dsp.h>
68 #include <asterisk/translate.h>
69 #include <asterisk/file.h>
70 #include <asterisk/callerid.h>
71 #include <asterisk/indications.h>
72 #include <asterisk/app.h>
73 #include <asterisk/features.h>
74 #include <asterisk/sched.h>
83 struct admin_list *next;
85 } *admin_first = NULL;
88 * channel and call instances
90 struct chan_call *call_first;
92 struct chan_call *find_call_ref(unsigned long ref)
94 struct chan_call *call = call_first;
105 struct chan_call *find_call_handle(unsigned long handle)
107 struct chan_call *call = call_first;
111 if (call->bchannel_handle == handle)
118 struct chan_call *alloc_call(void)
120 struct chan_call **callp = &call_first;
123 callp = &((*callp)->next);
125 *callp = (struct chan_call *)malloc(sizeof(struct chan_call));
129 void free_call(struct chan_call *call)
131 struct chan_call **temp = &call_first;
137 *temp = (*temp)->next;
141 temp = &((*temp)->next);
145 unsigned short new_brige_id(void)
147 struct chan_call *call;
148 unsigned short id = 1;
150 /* search for lowest bridge id that is not in use and not 0 */
156 if (call->bridge_id == id)
169 * receive bchannel data
171 void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
175 void rx_dtmf(struct bchannel *bchannel, char tone)
180 * enque message to LCR
182 int send_message(int message_type, unsigned long ref, union parameter *param)
184 struct admin_list *admin, **adminp;
186 adminp = &admin_first;
188 adminp = &((*adminp)->next);
189 admin = (struct admin_list *)malloc(sizeof(struct admin_list));
192 admin->msg.type = message_type;
193 admin->msg.ref = ref;
194 memcpy(&admin->msg.param, param, sizeof(union parameter));
200 * message received from LCR
202 int receive_message(int message_type, unsigned long ref, union parameter *param)
204 union parameter newparam;
205 struct bchannel *bchannel;
206 struct chan_call *call;
208 memset(&newparam, 0, sizeof(union parameter));
210 /* handle bchannel message*/
211 if (message_type == MESSAGE_BCHANNEL)
213 switch(param->bchannel.type)
215 case BCHANNEL_ASSIGN:
216 if ((bchannel = find_bchannel_handle(param->bchannel.handle)))
218 fprintf(stderr, "error: bchannel handle %x already assigned.\n", (int)param->bchannel.handle);
221 /* create bchannel */
222 bchannel = alloc_bchannel(param->bchannel.handle);
225 fprintf(stderr, "error: alloc bchannel handle %x failed.\n", (int)param->bchannel.handle);
229 /* configure channel */
230 bchannel->b_tx_gain = param->bchannel.tx_gain;
231 bchannel->b_rx_gain = param->bchannel.rx_gain;
232 strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
233 if (param->bchannel.crypt_len)
235 bchannel->b_crypt_len = param->bchannel.crypt_len;
236 bchannel->b_crypt_type = param->bchannel.crypt_type;
237 memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
239 bchannel->b_txdata = 0;
240 bchannel->b_dtmf = 1;
241 bchannel->b_tx_dejitter = 1;
243 /* in case, ref is not set, this bchannel instance must
244 * be created until it is removed again by LCR */
246 if ((call = find_call_ref(ref)))
249 call->bchannel_handle = param->bchannel.handle;
250 #warning hier muesen alle stati gesetzt werden falls sie vor dem b-kanal verfügbar waren
251 bchannel_join(bchannel, call->bridge_id);
253 if (bchannel_create(bchannel))
254 bchannel_activate(bchannel, 1);
257 newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
258 newparam.bchannel.handle = param->bchannel.handle;
259 send_message(MESSAGE_BCHANNEL, 0, &newparam);
262 case BCHANNEL_REMOVE:
263 if (!(bchannel = find_bchannel_handle(param->bchannel.handle)))
265 #warning alle fprintf nach ast_log
266 fprintf(stderr, "error: bchannel handle %x not assigned.\n", (int)param->bchannel.handle);
269 /* unlink from call */
270 if ((call = find_call_ref(bchannel->ref)))
272 call->bchannel_handle = 0;
274 /* destroy and remove bchannel */
275 free_bchannel(bchannel);
278 newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
279 newparam.bchannel.handle = param->bchannel.handle;
280 send_message(MESSAGE_BCHANNEL, 0, &newparam);
285 fprintf(stderr, "received unknown bchannel message %d\n", param->bchannel.type);
291 if (message_type == MESSAGE_NEWREF)
293 if (param->direction)
295 /* new ref from lcr */
296 if (!ref || find_call_ref(ref))
298 fprintf(stderr, "illegal new ref %d received\n", ref);
305 /* new ref, as requested from this remote application */
306 call = find_call_ref(0);
309 /* send release, if ref does not exist */
310 newparam.disconnectinfo.cause = CAUSE_NORMAL;
311 newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
312 send_message(MESSAGE_RELEASE, ref, &newparam);
316 #warning process call (send setup, if pending)
324 fprintf(stderr, "received message %d without ref\n", message_type);
327 call = find_call_ref(ref);
330 /* ignore ref that is not used (anymore) */
334 /* handle messages */
341 case MESSAGE_OVERLAP:
345 case MESSAGE_PROCEEDING:
349 case MESSAGE_ALERTING:
353 case MESSAGE_CONNECT:
357 case MESSAGE_DISCONNECT:
361 case MESSAGE_RELEASE:
366 case MESSAGE_INFORMATION:
370 case MESSAGE_FACILITY:
374 case MESSAGE_PATTERN:
378 case MESSAGE_NOPATTERN:
382 case MESSAGE_AUDIOPATH:
394 * warning! not thread safe
395 * returns -1 for socket error, 0 for no work, 1 for work
397 int handle_socket(void)
401 struct admin_message msg;
402 struct admin_list *admin;
406 #warning SOCKET FEHLT!
407 /* read from socket */
408 len = read(sock, &msg, sizeof(msg));
411 printf("Socket closed\n");
412 return(-1); // socket closed
416 if (len != sizeof(msg))
418 fprintf(stderr, "Socket short read (%d)\n", len);
419 return(-1); // socket error
421 if (msg.message != ADMIN_MESSAGE)
423 fprintf(stderr, "Socket received illegal message %d\n", msg.message);
424 return(-1); // socket error
426 receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
427 printf("message received %d\n", msg.u.msg.type);
431 if (errno != EWOULDBLOCK)
433 fprintf(stderr, "Socket error %d\n", errno);
438 /* write to socket */
442 len = write(sock, &admin->msg, sizeof(msg));
445 printf("Socket closed\n");
446 return(-1); // socket closed
450 if (len != sizeof(msg))
452 fprintf(stderr, "Socket short write (%d)\n", len);
453 return(-1); // socket error
456 admin_first = admin->next;
462 if (errno != EWOULDBLOCK)
464 fprintf(stderr, "Socket error %d\n", errno);
473 * open and close socket
475 int open_socket(void)
479 char *socket_name = SOCKET_NAME;
481 struct sockaddr_un sock_address;
482 unsigned long on = 1;
483 union parameter param;
486 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
488 ast_log(LOG_ERROR, "Failed to create socket.\n");
492 /* set socket address and name */
493 memset(&sock_address, 0, sizeof(sock_address));
494 sock_address.sun_family = PF_UNIX;
495 strcpy(sock_address.sun_path, socket_name);
498 if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
501 ast_log(LOG_ERROR, "Failed to connect to socket \"%s\". Is LCR running?\n", sock_address.sun_path);
505 /* set non-blocking io */
506 if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
509 ast_log(LOG_ERROR, "Failed to set socket into non-blocking IO.\n");
513 /* enque hello message */
514 memset(¶m, 0, sizeof(param));
515 strcpy(param.hello.application, "asterisk");
516 send_message(MESSAGE_HELLO, 0, ¶m);
521 void close_socket(int sock)
529 void lcr_thread(void)
538 int ret = handle_socket();
545 ret = bchannel_handle();
554 static struct ast_channel *lcr_request(const char *type, int format, void *data, int *cause)
560 /* call from asterisk (new instance) */
561 static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
563 struct lcr_pvt *lcr=ast->tech_pvt;
568 char *port_str, *dad, *p;
570 ast_copy_string(buf, dest, sizeof(buf)-1);
572 port_str=strsep(&p, "/");
576 ast_verbose("Call: ext:%s dest:(%s) -> dad(%s) \n", ast->exten,dest, dad);
582 static int lcr_answer(struct ast_channel *c)
584 struct lcr_pvt *lcr=c->tech_pvt;
588 static int lcr_hangup(struct ast_channel *c)
590 struct lcr_pvt *lcr=c->tech_pvt;
595 static int lcr_write(struct ast_channel *c, struct ast_frame *f)
597 struct lcr_pvt *lcrm= c->tech_pvt;
601 static struct ast_frame *lcr_read(struct ast_channel *c)
603 struct lcr_pvt *lcr = c->tech_pvt;
606 static int lcr_indicate(struct ast_channel *c, int cond, const void *data, size_t datalen)
611 case AST_CONTROL_BUSY:
612 case AST_CONTROL_CONGESTION:
613 case AST_CONTROL_RINGING:
618 case AST_CONTROL_VIDUPDATE:
621 case AST_CONTROL_HOLD:
622 ast_verbose(" << Console Has Been Placed on Hold >> \n");
623 //ast_moh_start(c, data, g->mohinterpret);
625 case AST_CONTROL_UNHOLD:
626 ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
631 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
638 static struct ast_channel_tech lcr_tech = {
640 .description="Channel driver for connecting to Linux-Call-Router",
641 .capabilities=AST_FORMAT_ALAW,
642 .requester=lcr_request,
643 // .send_digit=lcr_digit,
645 // .bridge=lcr_bridge,
650 .indicate=lcr_indicate,
652 // .send_text=lcr_send_text,
658 * module loading and destruction
660 int load_module(void)
662 // ast_mutex_init(&release_lock);
664 // lcr_cfg_update_ptp();
666 if (!(lcr_sock = open_socket())) {
667 ast_log(LOG_ERROR, "Unable to connect\n");
669 /* continue with closed socket */
672 if (!bchannel_initialize()) {
673 ast_log(LOG_ERROR, "Unable to open mISDN device\n");
678 if (ast_channel_register(&lcr_tech)) {
679 ast_log(LOG_ERROR, "Unable to register channel class\n");
683 //lcr_cfg_get( 0, LCR_GEN_TRACEFILE, global_tracefile, BUFFERSIZE);
688 int unload_module(void)
690 /* First, take us out of the channel loop */
691 ast_log(LOG_VERBOSE, "-- Unregistering mISDN Channel Driver --\n");
694 ast_channel_unregister(&lcr_tech);
697 bchannel_deinitialize();
709 static int reload_module(void)
716 ast_mutex_t usecnt_lock;
722 ast_mutex_lock(&usecnt_lock);
724 ast_mutex_unlock(&usecnt_lock);
729 char *desc="Channel driver for lcr";
731 char *description(void)
738 return ASTERISK_GPL_KEY;
741 #define AST_MODULE "chan_lcr"
742 AST_MODULE_INFO(ASTERISK_GPL_KEY,
744 "Channel driver for lcr",
746 .unload = unload_module,
747 .reload = reload_module,