DAHDI Barge support. More...
#include "asterisk.h"
#include <dahdi/user.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/app.h"
#include "asterisk/cli.h"
#include "asterisk/say.h"
#include "asterisk/utils.h"
Go to the source code of this file.
Defines | |
#define | CONF_SIZE 160 |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | careful_write (int fd, unsigned char *data, int len) |
static int | conf_exec (struct ast_channel *chan, void *data) |
static int | conf_run (struct ast_channel *chan, int confno, int confflags) |
static int | load_module (void) |
static int | unload_module (void) |
Variables | |
static struct ast_module_info __MODULE_INFO_SECTION | __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Barge in on DAHDI channel application" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } |
static char * | app = "DAHDIBarge" |
static struct ast_module_info * | ast_module_info = &__mod_info |
DAHDI Barge support.
Definition in file app_dahdibarge.c.
#define CONF_SIZE 160 |
Definition at line 75 of file app_dahdibarge.c.
Referenced by conf_run().
static void __reg_module | ( | void | ) | [static] |
Definition at line 308 of file app_dahdibarge.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 308 of file app_dahdibarge.c.
static int careful_write | ( | int | fd, |
unsigned char * | data, | ||
int | len | ||
) | [static] |
Definition at line 77 of file app_dahdibarge.c.
References ast_log(), errno, and LOG_WARNING.
Referenced by conf_run().
{ int res; while(len) { res = write(fd, data, len); if (res < 1) { if (errno != EAGAIN) { ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno)); return -1; } else return 0; } len -= res; data += res; } return 0; }
static int conf_exec | ( | struct ast_channel * | chan, |
void * | data | ||
) | [static] |
Definition at line 261 of file app_dahdibarge.c.
References ast_channel::_state, ast_answer(), ast_app_getdata(), ast_log(), AST_STATE_UP, ast_strlen_zero(), conf_run(), and LOG_WARNING.
Referenced by load_module().
{ int res = -1; int retrycnt = 0; int confflags = 0; int confno = 0; char confnostr[80] = ""; if (!ast_strlen_zero(data)) { if ((sscanf(data, "DAHDI/%30d", &confno) != 1) && (sscanf(data, "%30d", &confno) != 1)) { ast_log(LOG_WARNING, "DAHDIBarge Argument (if specified) must be a channel number, not '%s'\n", (char *)data); return 0; } } if (chan->_state != AST_STATE_UP) ast_answer(chan); while(!confno && (++retrycnt < 4)) { /* Prompt user for conference number */ confnostr[0] = '\0'; res = ast_app_getdata(chan, "conf-getchannel",confnostr, sizeof(confnostr) - 1, 0); if (res <0) goto out; if (sscanf(confnostr, "%30d", &confno) != 1) confno = 0; } if (confno) { /* XXX Should prompt user for pin if pin is required XXX */ /* Run the conference */ res = conf_run(chan, confno, confflags); } out: /* Do the conference */ return res; }
static int conf_run | ( | struct ast_channel * | chan, |
int | confno, | ||
int | confflags | ||
) | [static] |
Definition at line 95 of file app_dahdibarge.c.
References ast_debug, AST_FORMAT_ULAW, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree, AST_FRIENDLY_OFFSET, ast_indicate(), ast_log(), ast_read(), ast_set_read_format(), ast_set_write_format(), ast_waitfor_nandfds(), ast_write(), buf, careful_write(), CONF_SIZE, ast_frame::data, ast_frame::datalen, errno, f, ast_channel::fds, ast_frame::flags, ast_frame::frametype, LOG_WARNING, ast_channel::name, ast_frame::offset, ast_frame::ptr, ast_frame::samples, ast_frame::subclass, ast_channel::tech, and ast_channel_tech::type.
Referenced by conf_exec().
{ int fd; struct dahdi_confinfo dahdic; struct ast_frame *f; struct ast_channel *c; struct ast_frame fr; int outfd; int ms; int nfds; int res; int flags; int retrydahdi; int origfd; int ret = -1; struct dahdi_bufferinfo bi; char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET]; char *buf = __buf + AST_FRIENDLY_OFFSET; /* Set it into U-law mode (write) */ if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) { ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name); goto outrun; } /* Set it into U-law mode (read) */ if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) { ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name); goto outrun; } ast_indicate(chan, -1); retrydahdi = strcasecmp(chan->tech->type, "DAHDI"); dahdiretry: origfd = chan->fds[0]; if (retrydahdi) { fd = open("/dev/dahdi/pseudo", O_RDWR); if (fd < 0) { ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); goto outrun; } /* Make non-blocking */ flags = fcntl(fd, F_GETFL); if (flags < 0) { ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno)); close(fd); goto outrun; } if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) { ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno)); close(fd); goto outrun; } /* Setup buffering information */ memset(&bi, 0, sizeof(bi)); bi.bufsize = CONF_SIZE; bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; bi.numbufs = 4; if (ioctl(fd, DAHDI_SET_BUFINFO, &bi)) { ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno)); close(fd); goto outrun; } nfds = 1; } else { /* XXX Make sure we're not running on a pseudo channel XXX */ fd = chan->fds[0]; nfds = 0; } memset(&dahdic, 0, sizeof(dahdic)); /* Check to see if we're in a conference... */ dahdic.chan = 0; if (ioctl(fd, DAHDI_GETCONF, &dahdic)) { ast_log(LOG_WARNING, "Error getting conference\n"); close(fd); goto outrun; } if (dahdic.confmode) { /* Whoa, already in a conference... Retry... */ if (!retrydahdi) { ast_debug(1, "DAHDI channel is in a conference already, retrying with pseudo\n"); retrydahdi = 1; goto dahdiretry; } } memset(&dahdic, 0, sizeof(dahdic)); /* Add us to the conference */ dahdic.chan = 0; dahdic.confno = confno; dahdic.confmode = DAHDI_CONF_MONITORBOTH; if (ioctl(fd, DAHDI_SETCONF, &dahdic)) { ast_log(LOG_WARNING, "Error setting conference\n"); close(fd); goto outrun; } ast_debug(1, "Placed channel %s in DAHDI channel %d monitor\n", chan->name, confno); for(;;) { outfd = -1; ms = -1; c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms); if (c) { if (c->fds[0] != origfd) { if (retrydahdi) { /* Kill old pseudo */ close(fd); } ast_debug(1, "Ooh, something swapped out under us, starting over\n"); retrydahdi = 0; goto dahdiretry; } f = ast_read(c); if (!f) break; if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) { ret = 0; ast_frfree(f); break; } else if (fd != chan->fds[0]) { if (f->frametype == AST_FRAME_VOICE) { if (f->subclass == AST_FORMAT_ULAW) { /* Carefully write */ careful_write(fd, f->data.ptr, f->datalen); } else ast_log(LOG_WARNING, "Huh? Got a non-ulaw (%d) frame in the conference\n", f->subclass); } } ast_frfree(f); } else if (outfd > -1) { res = read(outfd, buf, CONF_SIZE); if (res > 0) { memset(&fr, 0, sizeof(fr)); fr.frametype = AST_FRAME_VOICE; fr.subclass = AST_FORMAT_ULAW; fr.datalen = res; fr.samples = res; fr.data.ptr = buf; fr.offset = AST_FRIENDLY_OFFSET; if (ast_write(chan, &fr) < 0) { ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno)); /* break; */ } } else ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno)); } } if (fd != chan->fds[0]) close(fd); else { /* Take out of conference */ /* Add us to the conference */ dahdic.chan = 0; dahdic.confno = 0; dahdic.confmode = 0; if (ioctl(fd, DAHDI_SETCONF, &dahdic)) { ast_log(LOG_WARNING, "Error setting conference\n"); } } outrun: return ret; }
static int load_module | ( | void | ) | [static] |
Definition at line 303 of file app_dahdibarge.c.
References AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application_xml, and conf_exec().
{ return ((ast_register_application_xml(app, conf_exec)) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS); }
static int unload_module | ( | void | ) | [static] |
Definition at line 298 of file app_dahdibarge.c.
References ast_unregister_application().
{ return ast_unregister_application(app); }
struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Barge in on DAHDI channel application" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static] |
Definition at line 308 of file app_dahdibarge.c.
char* app = "DAHDIBarge" [static] |
Definition at line 73 of file app_dahdibarge.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 308 of file app_dahdibarge.c.