Sat Aug 6 00:39:35 2011

Asterisk developer's documentation


app_nbscat.c File Reference

Silly application to play an NBScat file -- uses nbscat8k. More...

#include "asterisk.h"
#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/capability.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/frame.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/options.h"

Go to the source code of this file.

Defines

#define AF_LOCAL   AF_UNIX
#define LOCAL_NBSCAT   "/usr/local/bin/nbscat8k"
#define NBSCAT   "/usr/bin/nbscat8k"

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int load_module (void)
static int NBScat_exec (struct ast_channel *chan, void *data)
static int NBScatplay (int fd)
static int timed_read (int fd, void *data, int datalen)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Silly NBS Stream Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, }
static char * app = "NBScat"
static const struct ast_module_infoast_module_info = &__mod_info
static char * descrip
static char * synopsis = "Play an NBS local stream"


Detailed Description

Silly application to play an NBScat file -- uses nbscat8k.

Author:
Mark Spencer <markster@digium.com>

Definition in file app_nbscat.c.


Define Documentation

#define AF_LOCAL   AF_UNIX

Definition at line 62 of file app_nbscat.c.

#define LOCAL_NBSCAT   "/usr/local/bin/nbscat8k"

Definition at line 58 of file app_nbscat.c.

Referenced by NBScatplay().

#define NBSCAT   "/usr/bin/nbscat8k"

Definition at line 59 of file app_nbscat.c.

Referenced by NBScatplay().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 256 of file app_nbscat.c.

static void __unreg_module ( void   )  [static]

Definition at line 256 of file app_nbscat.c.

static int load_module ( void   )  [static]

Definition at line 251 of file app_nbscat.c.

References ast_register_application(), and NBScat_exec().

00252 {
00253    return ast_register_application(app, NBScat_exec, synopsis, descrip);
00254 }

static int NBScat_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 135 of file app_nbscat.c.

References AF_LOCAL, AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree, AST_FRIENDLY_OFFSET, ast_log(), ast_module_user_add, ast_module_user_remove, ast_read(), ast_samp2tv(), ast_set_write_format(), ast_stopstream(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_waitfor(), ast_write(), f, LOG_DEBUG, LOG_WARNING, NBScatplay(), offset, timed_read(), and ast_channel::writeformat.

Referenced by load_module().

00136 {
00137    int res=0;
00138    struct ast_module_user *u;
00139    int fds[2];
00140    int ms = -1;
00141    int pid = -1;
00142    int owriteformat;
00143    struct timeval next;
00144    struct ast_frame *f;
00145    struct myframe {
00146       struct ast_frame f;
00147       char offset[AST_FRIENDLY_OFFSET];
00148       short frdata[160];
00149    } myf;
00150    
00151    u = ast_module_user_add(chan);
00152 
00153    if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) {
00154       ast_log(LOG_WARNING, "Unable to create socketpair\n");
00155       ast_module_user_remove(u);
00156       return -1;
00157    }
00158    
00159    ast_stopstream(chan);
00160 
00161    owriteformat = chan->writeformat;
00162    res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
00163    if (res < 0) {
00164       ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
00165       ast_module_user_remove(u);
00166       return -1;
00167    }
00168    
00169    res = NBScatplay(fds[1]);
00170    /* Wait 1000 ms first */
00171    next = ast_tvnow();
00172    next.tv_sec += 1;
00173    if (res >= 0) {
00174       pid = res;
00175       /* Order is important -- there's almost always going to be mp3...  we want to prioritize the
00176          user */
00177       for (;;) {
00178          ms = ast_tvdiff_ms(next, ast_tvnow());
00179          if (ms <= 0) {
00180             res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata));
00181             if (res > 0) {
00182                myf.f.frametype = AST_FRAME_VOICE;
00183                myf.f.subclass = AST_FORMAT_SLINEAR;
00184                myf.f.datalen = res;
00185                myf.f.samples = res / 2;
00186                myf.f.mallocd = 0;
00187                myf.f.offset = AST_FRIENDLY_OFFSET;
00188                myf.f.src = __PRETTY_FUNCTION__;
00189                myf.f.delivery.tv_sec = 0;
00190                myf.f.delivery.tv_usec = 0;
00191                myf.f.data = myf.frdata;
00192                if (ast_write(chan, &myf.f) < 0) {
00193                   res = -1;
00194                   break;
00195                }
00196             } else {
00197                ast_log(LOG_DEBUG, "No more mp3\n");
00198                res = 0;
00199                break;
00200             }
00201             next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000));
00202          } else {
00203             ms = ast_waitfor(chan, ms);
00204             if (ms < 0) {
00205                ast_log(LOG_DEBUG, "Hangup detected\n");
00206                res = -1;
00207                break;
00208             }
00209             if (ms) {
00210                f = ast_read(chan);
00211                if (!f) {
00212                   ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
00213                   res = -1;
00214                   break;
00215                }
00216                if (f->frametype == AST_FRAME_DTMF) {
00217                   ast_log(LOG_DEBUG, "User pressed a key\n");
00218                   ast_frfree(f);
00219                   res = 0;
00220                   break;
00221                }
00222                ast_frfree(f);
00223             } 
00224          }
00225       }
00226    }
00227    close(fds[0]);
00228    close(fds[1]);
00229    
00230    if (pid > -1)
00231       kill(pid, SIGKILL);
00232    if (!res && owriteformat)
00233       ast_set_write_format(chan, owriteformat);
00234 
00235    ast_module_user_remove(u);
00236 
00237    return res;
00238 }

static int NBScatplay ( int  fd  )  [static]

Definition at line 74 of file app_nbscat.c.

References ast_log(), ast_opt_high_priority, ast_set_priority(), LOCAL_NBSCAT, LOG_WARNING, and NBSCAT.

Referenced by NBScat_exec().

00075 {
00076    int res;
00077    int x;
00078    sigset_t fullset, oldset;
00079 #ifdef HAVE_CAP
00080    cap_t cap;
00081 #endif
00082 
00083    sigfillset(&fullset);
00084    pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
00085 
00086    res = fork();
00087    if (res < 0) 
00088       ast_log(LOG_WARNING, "Fork failed\n");
00089    if (res) {
00090       pthread_sigmask(SIG_SETMASK, &oldset, NULL);
00091       return res;
00092    }
00093    signal(SIGPIPE, SIG_DFL);
00094    pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
00095 
00096 #ifdef HAVE_CAP
00097    cap = cap_from_text("cap_net_admin-eip");
00098 
00099    if (cap_set_proc(cap)) {
00100       /* Careful with order! Logging cannot happen after we close FDs */
00101       ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
00102    }
00103    cap_free(cap);
00104 #endif
00105    if (ast_opt_high_priority)
00106       ast_set_priority(0);
00107 
00108    dup2(fd, STDOUT_FILENO);
00109    for (x = STDERR_FILENO + 1; x < 1024; x++) {
00110       if (x != STDOUT_FILENO)
00111          close(x);
00112    }
00113    /* Most commonly installed in /usr/local/bin */
00114    execl(NBSCAT, "nbscat8k", "-d", (char *)NULL);
00115    execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL);
00116    ast_log(LOG_WARNING, "Execute of nbscat8k failed\n");
00117    _exit(0);
00118 }

static int timed_read ( int  fd,
void *  data,
int  datalen 
) [static]

Definition at line 120 of file app_nbscat.c.

References ast_log(), ast_poll, and LOG_NOTICE.

00121 {
00122    int res;
00123    struct pollfd fds[1];
00124    fds[0].fd = fd;
00125    fds[0].events = POLLIN;
00126    res = ast_poll(fds, 1, 2000);
00127    if (res < 1) {
00128       ast_log(LOG_NOTICE, "Selected timed out/errored out with %d\n", res);
00129       return -1;
00130    }
00131    return read(fd, data, datalen);
00132    
00133 }

static int unload_module ( void   )  [static]

Definition at line 240 of file app_nbscat.c.

References ast_module_user_hangup_all, and ast_unregister_application().

00241 {
00242    int res;
00243 
00244    res = ast_unregister_application(app);
00245 
00246    ast_module_user_hangup_all();
00247 
00248    return res;
00249 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Silly NBS Stream Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 256 of file app_nbscat.c.

char* app = "NBScat" [static]

Definition at line 65 of file app_nbscat.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 256 of file app_nbscat.c.

char* descrip [static]

Initial value:

 
"  NBScat: Executes nbscat to listen to the local NBS stream.\n"
"User can exit by pressing any key\n."

Definition at line 69 of file app_nbscat.c.

char* synopsis = "Play an NBS local stream" [static]

Definition at line 67 of file app_nbscat.c.


Generated on Sat Aug 6 00:39:35 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7