From af6016cfd01117135950c8d962b0dd0c6d73af36 Mon Sep 17 00:00:00 2001 From: Mark Spencer Date: Sat, 20 Mar 2004 07:16:27 +0000 Subject: Add experimental nbscat application git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@2490 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/Makefile | 3 +- apps/app_nbscat.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+), 1 deletion(-) create mode 100755 apps/app_nbscat.c (limited to 'apps') diff --git a/apps/Makefile b/apps/Makefile index 06d09a30d..b8a82ea82 100755 --- a/apps/Makefile +++ b/apps/Makefile @@ -25,7 +25,8 @@ APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_mp3.so\ app_waitforring.so app_privacy.so app_db.so app_chanisavail.so \ app_enumlookup.so app_transfer.so app_setcidnum.so app_cdr.so \ app_hasnewvoicemail.so app_sayunixtime.so app_cut.so app_read.so \ - app_setcdruserfield.so app_random.so app_ices.so app_eval.so + app_setcdruserfield.so app_random.so app_ices.so app_eval.so \ + app_nbscat.so ifneq (${OSARCH},Darwin) APPS+=app_intercom.so diff --git a/apps/app_nbscat.c b/apps/app_nbscat.c new file mode 100755 index 000000000..e99d2f265 --- /dev/null +++ b/apps/app_nbscat.c @@ -0,0 +1,206 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * Silly application to play an NBScat file -- uses mpg123 + * + * Copyright (C) 1999, Mark Spencer + * + * Mark Spencer + * + * This program is free software, distributed under the terms of + * the GNU General Public License + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOCAL_NBSCAT "/usr/local/bin/nbscat8k" +#define NBSCAT "/usr/bin/nbscat8k" + +static char *tdesc = "Silly NBS Stream Application"; + +static char *app = "NBScat"; + +static char *synopsis = "Play an NBS local stream"; + +static char *descrip = +" NBScat: Executes nbscat to listen to the local NBS stream.\n" +"Returns -1 on\n hangup or 0 otherwise. User can exit by \n" +"pressing any key\n."; + +STANDARD_LOCAL_USER; + +LOCAL_USER_DECL; + +static int NBScatplay(int fd) +{ + int res; + int x; + res = fork(); + if (res < 0) + ast_log(LOG_WARNING, "Fork failed\n"); + if (res) + return res; + dup2(fd, STDOUT_FILENO); + for (x=0;x<256;x++) { + if (x != STDOUT_FILENO) + close(x); + } + /* Most commonly installed in /usr/local/bin */ + execl(NBSCAT, "nbscat8k", "-d", (char *)NULL); + execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL); + ast_log(LOG_WARNING, "Execute of nbscat8k failed\n"); + return -1; +} + +static int timed_read(int fd, void *data, int datalen) +{ + int res; + fd_set fds; + struct timeval tv = { 2, 0 }; /* Wait no more than 2 seconds */ + FD_ZERO(&fds); + FD_SET(fd, &fds); + res = ast_select(fd + 1, &fds, NULL, NULL, &tv); + if (res < 1) { + ast_log(LOG_NOTICE, "Selected timed out/errored out with %d\n", res); + return -1; + } + return read(fd, data, datalen); + +} + +static int NBScat_exec(struct ast_channel *chan, void *data) +{ + int res=0; + struct localuser *u; + int fds[2]; + int ms = -1; + int pid = -1; + int owriteformat; + struct timeval last; + struct ast_frame *f; + struct myframe { + struct ast_frame f; + char offset[AST_FRIENDLY_OFFSET]; + short frdata[160]; + } myf; + last.tv_usec = 0; + last.tv_sec = 0; + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) { + ast_log(LOG_WARNING, "Unable to create socketpair\n"); + return -1; + } + LOCAL_USER_ADD(u); + ast_stopstream(chan); + + owriteformat = chan->writeformat; + res = ast_set_write_format(chan, AST_FORMAT_SLINEAR); + if (res < 0) { + ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); + return -1; + } + + res = NBScatplay(fds[1]); + /* Wait 1000 ms first */ + ms = 1000; + if (res >= 0) { + pid = res; + /* Order is important -- there's almost always going to be NBScat... we want to prioritize the + user */ + for (;;) { + ms = ast_waitfor(chan, ms); + if (ms < 0) { + ast_log(LOG_DEBUG, "Hangup detected\n"); + res = -1; + break; + } + if (ms) { + f = ast_read(chan); + if (!f) { + ast_log(LOG_DEBUG, "Null frame == hangup() detected\n"); + res = -1; + break; + } + if (f->frametype == AST_FRAME_DTMF) { + ast_log(LOG_DEBUG, "User pressed a key\n"); + ast_frfree(f); + res = 0; + break; + } + ast_frfree(f); + } else { + res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata)); + if (res > 0) { + myf.f.frametype = AST_FRAME_VOICE; + myf.f.subclass = AST_FORMAT_SLINEAR; + myf.f.datalen = res; + myf.f.samples = res / 2; + myf.f.mallocd = 0; + myf.f.offset = AST_FRIENDLY_OFFSET; + myf.f.src = __PRETTY_FUNCTION__; + myf.f.data = myf.frdata; + if (ast_write(chan, &myf.f) < 0) { + res = -1; + break; + } + } else { + ast_log(LOG_DEBUG, "No more NBScat\n"); + res = 0; + break; + } + ms = res / 16; + } + } + } + close(fds[0]); + close(fds[1]); + LOCAL_USER_REMOVE(u); + if (pid > -1) + kill(pid, SIGKILL); + if (!res && owriteformat) + ast_set_write_format(chan, owriteformat); + return res; +} + +int unload_module(void) +{ + STANDARD_HANGUP_LOCALUSERS; + return ast_unregister_application(app); +} + +int load_module(void) +{ + return ast_register_application(app, NBScat_exec, synopsis, descrip); +} + +char *description(void) +{ + return tdesc; +} + +int usecount(void) +{ + int res; + STANDARD_USECOUNT(res); + return res; +} + +char *key() +{ + return ASTERISK_GPL_KEY; +} -- cgit v1.2.3