aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2003-02-04 15:48:42 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2003-02-04 15:48:42 +0000
commitbfeaccab3dc438565ef03fa961fee49805fd6eb8 (patch)
tree517ee94a20886f04c78a05a553831f5b081fed76 /apps
parent151774c059eebca84557de8bed5495b523bdd8b2 (diff)
Version 0.3.0 from FTP
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@600 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps')
-rwxr-xr-xapps/app_adsiprog.c5
-rwxr-xr-xapps/app_flash.c116
-rwxr-xr-xapps/app_meetme.c126
-rwxr-xr-xapps/app_milliwatt.c3
-rwxr-xr-xapps/app_zapbarge.c305
-rwxr-xr-xapps/app_zapras.c9
6 files changed, 541 insertions, 23 deletions
diff --git a/apps/app_adsiprog.c b/apps/app_adsiprog.c
index 531b2c423..4df6414eb 100755
--- a/apps/app_adsiprog.c
+++ b/apps/app_adsiprog.c
@@ -24,10 +24,13 @@
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
#include <pthread.h>
#include "../asterisk.h"
+#include "../astconf.h"
static char *tdesc = "Asterisk ADSI Programming Application";
@@ -1321,7 +1324,7 @@ static struct adsi_script *compile_script(char *script)
if (script[0] == '/')
strncpy(fn, script, sizeof(fn) - 1);
else
- snprintf(fn, sizeof(fn), "%s/%s", AST_CONFIG_DIR, script);
+ snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, script);
f = fopen(fn, "r");
if (!f) {
ast_log(LOG_WARNING, "Can't open file '%s'\n", fn);
diff --git a/apps/app_flash.c b/apps/app_flash.c
new file mode 100755
index 000000000..902b7506c
--- /dev/null
+++ b/apps/app_flash.c
@@ -0,0 +1,116 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * App to flash a zap trunk
+ *
+ * Copyright (C) 1999, Mark Spencer
+ *
+ * Mark Spencer <markster@linux-support.net>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License
+ */
+
+#include <asterisk/lock.h>
+#include <asterisk/file.h>
+#include <asterisk/logger.h>
+#include <asterisk/channel.h>
+#include <asterisk/pbx.h>
+#include <asterisk/module.h>
+#include <asterisk/translate.h>
+#include <asterisk/image.h>
+#include <asterisk/options.h>
+#include <sys/ioctl.h>
+#include <linux/zaptel.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+static char *tdesc = "Flash zap trunk application";
+
+static char *app = "Flash";
+
+static char *synopsis = "Flashes a Zap Trunk";
+
+static char *descrip =
+" Flash(): Sends a flash on a zap trunk. This is only a hack for\n"
+"people who want to perform transfers and such via AGI and is generally\n"
+"quite useless otherwise. Returns 0 on success or -1 if this is not\n"
+"a zap trunk\n";
+
+STANDARD_LOCAL_USER;
+
+LOCAL_USER_DECL;
+
+static inline int zt_wait_event(int fd)
+{
+ /* Avoid the silly zt_waitevent which ignores a bunch of events */
+ int i,j=0;
+ i = ZT_IOMUX_SIGEVENT;
+ if (ioctl(fd, ZT_IOMUX, &i) == -1) return -1;
+ if (ioctl(fd, ZT_GETEVENT, &j) == -1) return -1;
+ return j;
+}
+
+static int flash_exec(struct ast_channel *chan, void *data)
+{
+ int res = -1;
+ int x;
+ struct localuser *u;
+ struct zt_params ztp;
+ LOCAL_USER_ADD(u);
+ if (!strcasecmp(chan->type, "Zap")) {
+ memset(&ztp, 0, sizeof(ztp));
+ res = ioctl(chan->fds[0], ZT_GET_PARAMS, &ztp);
+ if (!res) {
+ if (ztp.sigtype & __ZT_SIG_FXS) {
+ x = ZT_FLASH;
+ res = ioctl(chan->fds[0], ZT_HOOK, &x);
+ if (!res || (errno == EINPROGRESS)) {
+ if (res) {
+ /* Wait for the event to finish */
+ zt_wait_event(chan->fds[0]);
+ }
+ res = ast_safe_sleep(chan, 1000);
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Flashed channel %s\n", chan->name);
+ } else
+ ast_log(LOG_WARNING, "Unable to flash channel %s: %s\n", chan->name, strerror(errno));
+ } else
+ ast_log(LOG_WARNING, "%s is not an FXO Channel\n", chan->name);
+ } else
+ ast_log(LOG_WARNING, "Unable to get parameters of %s: %s\n", chan->name, strerror(errno));
+ } else
+ ast_log(LOG_WARNING, "%s is not a Zap channel\n", chan->name);
+ LOCAL_USER_REMOVE(u);
+ return res;
+}
+
+int unload_module(void)
+{
+ STANDARD_HANGUP_LOCALUSERS;
+ return ast_unregister_application(app);
+}
+
+int load_module(void)
+{
+ return ast_register_application(app, flash_exec, synopsis, descrip);
+}
+
+char *description(void)
+{
+ return tdesc;
+}
+
+int usecount(void)
+{
+ int res;
+ STANDARD_USECOUNT(res);
+ return res;
+}
+
+char *key()
+{
+ return ASTERISK_GPL_KEY;
+}
diff --git a/apps/app_meetme.c b/apps/app_meetme.c
index cec00c339..91d53b992 100755
--- a/apps/app_meetme.c
+++ b/apps/app_meetme.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <errno.h>
#include <stdlib.h>
#include <sys/ioctl.h>
@@ -40,13 +41,20 @@ static char *synopsis = "Simple MeetMe conference bridge";
static char *synopsis2 = "MeetMe participant count";
static char *descrip =
-" MeetMe(confno): Enters the user into a specified MeetMe conference.\n"
+" MeetMe(confno[|options]): Enters the user into a specified MeetMe conference.\n"
"If the conference number is omitted, the user will be prompted to enter\n"
"one. This application always returns -1. A ZAPTEL INTERFACE MUST BE\n"
-"INSTALLED FOR CONFERENCING FUNCTIONALITY.\n";
+"INSTALLED FOR CONFERENCING FUNCTIONALITY.\n"
+"The option string may contain zero or more of the following characters:\n"
+" 'a' -- set admin mode\n"
+" 'm' -- set monitor only mode\n"
+" 'p' -- allow user to exit the conference by pressing '#'\n"
+" 's' -- send user to admin/user menu if '*' is received\n"
+" 't' -- set talk only mode\n"
+" 'q' -- quiet mode (don't play enter/leave sounds)\n";
static char *descrip2 =
-" MeetMe2(confno): Plays back the number of users in the specified MeetMe\n"
+" MeetMeCount(confno): Plays back the number of users in the specified MeetMe\n"
"conference. Returns 0 on success or -1 on a hangup. A ZAPTEL INTERFACE\n"
"MUST BE INSTALLED FOR CONFERENCING FUNCTIONALITY.\n";
@@ -73,6 +81,13 @@ static pthread_mutex_t conflock = AST_MUTEX_INITIALIZER;
#define CONF_SIZE 160
+#define CONFFLAG_ADMIN (1 << 1) /* If set the user has admin access on the conference */
+#define CONFFLAG_MONITOR (1 << 2) /* If set the user can only receive audio from the conference */
+#define CONFFLAG_POUNDEXIT (1 << 3) /* If set asterisk will exit conference when '#' is pressed */
+#define CONFFLAG_STARMENU (1 << 4) /* If set asterisk will provide a menu to the user what '*' is pressed */
+#define CONFFLAG_TALKER (1 << 5) /* If set the use can only send audio to the conference */
+#define CONFFLAG_QUIET (1 << 6) /* If set there will be no enter or leave sounds */
+
static int careful_write(int fd, unsigned char *data, int len)
{
int res;
@@ -153,7 +168,7 @@ static struct conf *build_conf(char *confno, int make)
cnf->start = time(NULL);
cnf->zapconf = ztc.confno;
if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Crated ZapTel conference %d for conference '%s'\n", cnf->zapconf, cnf->confno);
+ ast_verbose(VERBOSE_PREFIX_3 "Created ZapTel conference %d for conference '%s'\n", cnf->zapconf, cnf->confno);
cnf->next = confs;
confs = cnf;
} else
@@ -202,7 +217,7 @@ static struct ast_cli_entry cli_show_confs = {
{ "show", "conferences", NULL }, confs_show,
"Show status of conferences", show_confs_usage, NULL };
-static void conf_run(struct ast_channel *chan, struct conf *conf)
+static int conf_run(struct ast_channel *chan, struct conf *conf, int confflags)
{
struct conf *prev=NULL, *cur;
int fd;
@@ -215,12 +230,20 @@ static void conf_run(struct ast_channel *chan, struct conf *conf)
int nfds;
int res;
int flags;
- int retryzap=0;
+ int retryzap;
+ int origfd;
+ int firstpass = 0;
+ int ret = -1;
ZT_BUFFERINFO bi;
char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
char *buf = __buf + AST_FRIENDLY_OFFSET;
+ if (!(confflags & CONFFLAG_QUIET) && conf->users == 1) {
+ if (!ast_streamfile(chan, "conf-onlyperson", chan->language))
+ ast_waitstream(chan, "");
+ }
+
/* 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);
@@ -232,9 +255,11 @@ static void conf_run(struct ast_channel *chan, struct conf *conf)
ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name);
goto outrun;
}
+ ast_indicate(chan, -1);
+ retryzap = strcasecmp(chan->type, "Zap");
zapretry:
-
- if (retryzap || strcasecmp(chan->type, "Zap")) {
+ origfd = chan->fds[0];
+ if (retryzap) {
fd = open("/dev/zap/pseudo", O_RDWR);
if (fd < 0) {
ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
@@ -289,25 +314,53 @@ zapretry:
/* Add us to the conference */
ztc.chan = 0;
ztc.confno = conf->zapconf;
- ztc.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
+ if (confflags & CONFFLAG_MONITOR)
+ ztc.confmode = ZT_CONF_CONFMON | ZT_CONF_LISTENER;
+ else if (confflags & CONFFLAG_TALKER)
+ ztc.confmode = ZT_CONF_CONF | ZT_CONF_TALKER;
+ else
+ ztc.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
+
if (ioctl(fd, ZT_SETCONF, &ztc)) {
ast_log(LOG_WARNING, "Error setting conference\n");
close(fd);
goto outrun;
}
ast_log(LOG_DEBUG, "Placed channel %s in ZAP conf %d\n", chan->name, conf->zapconf);
- /* Run the conference enter tone... */
- conf_play(conf, ENTER);
+ if (!firstpass && !(confflags & CONFFLAG_MONITOR) && !(confflags & CONFFLAG_ADMIN)) {
+ firstpass = 1;
+ if (!(confflags & CONFFLAG_QUIET))
+ conf_play(conf, ENTER);
+ }
for(;;) {
outfd = -1;
ms = -1;
c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
if (c) {
+ if (c->fds[0] != origfd) {
+ if (retryzap) {
+ /* Kill old pseudo */
+ close(fd);
+ }
+ ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n");
+ retryzap = 0;
+ goto zapretry;
+ }
f = ast_read(c);
if (!f)
break;
- if (fd != chan->fds[0]) {
+ if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#') && (confflags & CONFFLAG_POUNDEXIT)) {
+ ret = 0;
+ break;
+ } else if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '*') && (confflags & CONFFLAG_STARMENU)) {
+ if ((confflags & CONFFLAG_ADMIN)) {
+ /* Do admin stuff here */
+ } else {
+ /* Do user menu here */
+ }
+
+ } else if (fd != chan->fds[0]) {
if (f->frametype == AST_FRAME_VOICE) {
if (f->subclass == AST_FORMAT_ULAW) {
/* Carefully write */
@@ -324,7 +377,7 @@ zapretry:
fr.frametype = AST_FRAME_VOICE;
fr.subclass = AST_FORMAT_ULAW;
fr.datalen = res;
- fr.timelen = res / 8;
+ fr.samples = res;
fr.data = buf;
fr.offset = AST_FRIENDLY_OFFSET;
if (ast_write(chan, &fr) < 0) {
@@ -348,7 +401,8 @@ zapretry:
}
}
- conf_play(conf, LEAVE);
+ if (!(confflags & CONFFLAG_QUIET) && !(confflags & CONFFLAG_MONITOR) && !(confflags & CONFFLAG_ADMIN))
+ conf_play(conf, LEAVE);
outrun:
@@ -375,6 +429,7 @@ outrun:
free(conf);
}
pthread_mutex_unlock(&conflock);
+ return ret;
}
static struct conf *find_conf(char *confno, int make)
@@ -435,6 +490,8 @@ static int conf_exec(struct ast_channel *chan, void *data)
int allowretry = 0;
int retrycnt = 0;
struct conf *cnf;
+ int confflags = 0;
+ char info[256], *ptr, *inflags, *inpin;
if (!data || !strlen(data)) {
allowretry = 1;
@@ -443,10 +500,41 @@ static int conf_exec(struct ast_channel *chan, void *data)
LOCAL_USER_ADD(u);
if (chan->_state != AST_STATE_UP)
ast_answer(chan);
-retry:
- /* Parse out the stuff */
- strncpy(confno, data, sizeof(confno) - 1);
+ strncpy(info, (char *)data, sizeof(info) - 1);
+ ptr = info;
+
+ if (info) {
+ inflags = strchr(info, '|');
+ if (inflags) {
+ *inflags = '\0';
+ inflags++;
+ if (strchr(inflags, 'a'))
+ confflags |= CONFFLAG_ADMIN;
+ if (strchr(inflags, 'm'))
+ confflags |= CONFFLAG_MONITOR;
+ if (strchr(inflags, 'p'))
+ confflags |= CONFFLAG_POUNDEXIT;
+ if (strchr(inflags, 's'))
+ confflags |= CONFFLAG_STARMENU;
+ if (strchr(inflags, 't'))
+ confflags |= CONFFLAG_TALKER;
+ if (strchr(inflags, 'q'))
+ confflags |= CONFFLAG_QUIET;
+
+ inpin = strchr(inflags, '|');
+ if (inpin) {
+ *inpin = '\0';
+ inpin++;
+ /* XXX Need to do something with pin XXX */
+ ast_log(LOG_WARNING, "MEETME WITH PIN=(%s)\n", inpin);
+ }
+ }
+ }
+
+ /* Parse out the stuff */
+ strncpy(confno, info, sizeof(confno) - 1);
+retry:
while(!strlen(confno) && (++retrycnt < 4)) {
/* Prompt user for conference number */
res = ast_app_getdata(chan, "conf-getconfno",confno, sizeof(confno) - 1, 0);
@@ -467,9 +555,9 @@ retry:
goto retry;
}
} else {
+ /* XXX Should prompt user for pin if pin is required XXX */
/* Run the conference */
- conf_run(chan, cnf);
- res = -1;
+ res = conf_run(chan, cnf, confflags);
}
}
out:
diff --git a/apps/app_milliwatt.c b/apps/app_milliwatt.c
index b117441df..b51d8b2dd 100755
--- a/apps/app_milliwatt.c
+++ b/apps/app_milliwatt.c
@@ -21,6 +21,7 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
+#include <errno.h>
#include <pthread.h>
@@ -73,7 +74,7 @@ static int milliwatt_generate(struct ast_channel *chan, void *data, int len)
wf.mallocd = 0;
wf.data = buf;
wf.datalen = len;
- wf.timelen = wf.datalen / 8;
+ wf.samples = wf.datalen;
wf.src = "app_milliwatt";
/* create a buffer containing the digital milliwatt pattern */
for(i = 0; i < len; i++)
diff --git a/apps/app_zapbarge.c b/apps/app_zapbarge.c
new file mode 100755
index 000000000..0b865df5b
--- /dev/null
+++ b/apps/app_zapbarge.c
@@ -0,0 +1,305 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Zap Barge support
+ *
+ * Copyright (C) 2003, Digium
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License
+ *
+ * Special thanks to comphealth.com for sponsoring this
+ * GPL application.
+ */
+
+#include <asterisk/lock.h>
+#include <asterisk/file.h>
+#include <asterisk/logger.h>
+#include <asterisk/channel.h>
+#include <asterisk/pbx.h>
+#include <asterisk/module.h>
+#include <asterisk/config.h>
+#include <asterisk/app.h>
+#include <asterisk/options.h>
+#include <asterisk/cli.h>
+#include <asterisk/say.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+
+#include <pthread.h>
+#include <linux/zaptel.h>
+static char *tdesc = "Barge in on Zap channel application";
+
+static char *app = "ZapBarge";
+
+static char *synopsis = "Barge in (monitor) Zap channel";
+
+static char *descrip =
+" ZapBarge([channel]): Barges in on a specified zap\n"
+"channel or prompts if one is not specified. Returns\n"
+"-1 when caller user hangs up and is independent of the\n"
+"state of the channel being monitored.";
+
+
+STANDARD_LOCAL_USER;
+
+LOCAL_USER_DECL;
+
+
+#define CONF_SIZE 160
+
+static int careful_write(int fd, unsigned char *data, int len)
+{
+ 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_run(struct ast_channel *chan, int confno, int confflags)
+{
+ int fd;
+ struct zt_confinfo ztc;
+ struct ast_frame *f;
+ struct ast_channel *c;
+ struct ast_frame fr;
+ int outfd;
+ int ms;
+ int nfds;
+ int res;
+ int flags;
+ int retryzap;
+ int origfd;
+ int ret = -1;
+
+ ZT_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);
+ retryzap = strcasecmp(chan->type, "Zap");
+zapretry:
+ origfd = chan->fds[0];
+ if (retryzap) {
+ fd = open("/dev/zap/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 = ZT_POLICY_IMMEDIATE;
+ bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
+ bi.numbufs = 4;
+ if (ioctl(fd, ZT_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(&ztc, 0, sizeof(ztc));
+ /* Check to see if we're in a conference... */
+ ztc.chan = 0;
+ if (ioctl(fd, ZT_GETCONF, &ztc)) {
+ ast_log(LOG_WARNING, "Error getting conference\n");
+ close(fd);
+ goto outrun;
+ }
+ if (ztc.confmode) {
+ /* Whoa, already in a conference... Retry... */
+ if (!retryzap) {
+ ast_log(LOG_DEBUG, "Zap channel is in a conference already, retrying with pseudo\n");
+ retryzap = 1;
+ goto zapretry;
+ }
+ }
+ memset(&ztc, 0, sizeof(ztc));
+ /* Add us to the conference */
+ ztc.chan = 0;
+ ztc.confno = confno;
+ ztc.confmode = ZT_CONF_MONITORBOTH;
+
+ if (ioctl(fd, ZT_SETCONF, &ztc)) {
+ ast_log(LOG_WARNING, "Error setting conference\n");
+ close(fd);
+ goto outrun;
+ }
+ ast_log(LOG_DEBUG, "Placed channel %s in ZAP 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 (retryzap) {
+ /* Kill old pseudo */
+ close(fd);
+ }
+ ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n");
+ retryzap = 0;
+ goto zapretry;
+ }
+ f = ast_read(c);
+ if (!f)
+ break;
+ if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) {
+ ret = 0;
+ 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, 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 = 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 */
+ ztc.chan = 0;
+ ztc.confno = 0;
+ ztc.confmode = 0;
+ if (ioctl(fd, ZT_SETCONF, &ztc)) {
+ ast_log(LOG_WARNING, "Error setting conference\n");
+ }
+ }
+
+outrun:
+
+ return ret;
+}
+
+static int conf_exec(struct ast_channel *chan, void *data)
+{
+ int res=-1;
+ struct localuser *u;
+ int retrycnt = 0;
+ int confflags = 0;
+ int confno = 0;
+ char confstr[80];
+
+ if (data && strlen(data)) {
+ if ((sscanf(data, "Zap/%d", &confno) != 1) &&
+ (sscanf(data, "%d", &confno) != 1)) {
+ ast_log(LOG_WARNING, "ZapBarge Argument (if specified) must be a channel number, not '%s'\n", (char *)data);
+ return 0;
+ }
+ }
+ LOCAL_USER_ADD(u);
+ if (chan->_state != AST_STATE_UP)
+ ast_answer(chan);
+
+ while(!confno && (++retrycnt < 4)) {
+ /* Prompt user for conference number */
+ strcpy(confstr, "");
+ res = ast_app_getdata(chan, "conf-getchannel",confstr, sizeof(confstr) - 1, 0);
+ if (res <0) goto out;
+ if (sscanf(confstr, "%d", &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 */
+ LOCAL_USER_REMOVE(u);
+ return res;
+}
+
+int unload_module(void)
+{
+ STANDARD_HANGUP_LOCALUSERS;
+ return ast_unregister_application(app);
+}
+
+int load_module(void)
+{
+ return ast_register_application(app, conf_exec, synopsis, descrip);
+}
+
+char *description(void)
+{
+ return tdesc;
+}
+
+int usecount(void)
+{
+ int res;
+ STANDARD_USECOUNT(res);
+ return res;
+}
+
+char *key()
+{
+ return ASTERISK_GPL_KEY;
+}
diff --git a/apps/app_zapras.c b/apps/app_zapras.c
index 7d2b0b83a..57a64ab5d 100755
--- a/apps/app_zapras.c
+++ b/apps/app_zapras.c
@@ -26,6 +26,9 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
#include <pthread.h>
@@ -60,6 +63,7 @@ static pid_t spawn_ras(struct ast_channel *chan, char *args)
char *argv[PPP_MAX_ARGS];
int argc = 0;
+ char *stringp=NULL;
/* Start by forking */
pid = fork();
@@ -86,10 +90,11 @@ static pid_t spawn_ras(struct ast_channel *chan, char *args)
argv[argc++] = "nodetach";
/* And all the other arguments */
- c = strtok(args, "|");
+ stringp=args;
+ c = strsep(&stringp, "|");
while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
argv[argc++] = c;
- c = strtok(NULL, "|");
+ c = strsep(&stringp, "|");
}
argv[argc++] = "plugin";