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.