Thu Apr 28 2011 16:56:51

Asterisk developer's documentation


app_nbscat.c File Reference

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

#include "asterisk.h"
#include <fcntl.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <signal.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/frame.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/app.h"
Include dependency graph for app_nbscat.c:

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
__MODULE_INFO_SECTION 
__mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Silly NBS Stream Application" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, }
static char * app = "NBScat"
static struct ast_module_infoast_module_info = &__mod_info

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 63 of file app_nbscat.c.

Referenced by NBScat_exec().

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

Definition at line 59 of file app_nbscat.c.

Referenced by NBScatplay().

#define NBSCAT   "/usr/bin/nbscat8k"

Definition at line 60 of file app_nbscat.c.

Referenced by NBScatplay().


Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 216 of file app_nbscat.c.

static void __unreg_module ( void  ) [static]

Definition at line 216 of file app_nbscat.c.

static int load_module ( void  ) [static]

Definition at line 211 of file app_nbscat.c.

References ast_register_application_xml, and NBScat_exec().

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

Definition at line 108 of file app_nbscat.c.

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

Referenced by load_module().

{
   int res=0;
   int fds[2];
   int ms = -1;
   int pid = -1;
   int owriteformat;
   struct timeval next;
   struct ast_frame *f;
   struct myframe {
      struct ast_frame f;
      char offset[AST_FRIENDLY_OFFSET];
      short frdata[160];
   } myf;
   
   if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) {
      ast_log(LOG_WARNING, "Unable to create socketpair\n");
      return -1;
   }
   
   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 */
   next = ast_tvnow();
   next.tv_sec += 1;
   if (res >= 0) {
      pid = res;
      /* Order is important -- there's almost always going to be mp3...  we want to prioritize the
         user */
      for (;;) {
         ms = ast_tvdiff_ms(next, ast_tvnow());
         if (ms <= 0) {
            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.delivery.tv_sec = 0;
               myf.f.delivery.tv_usec = 0;
               myf.f.data.ptr = myf.frdata;
               if (ast_write(chan, &myf.f) < 0) {
                  res = -1;
                  break;
               }
            } else {
               ast_debug(1, "No more mp3\n");
               res = 0;
               break;
            }
            next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000));
         } else {
            ms = ast_waitfor(chan, ms);
            if (ms < 0) {
               ast_debug(1, "Hangup detected\n");
               res = -1;
               break;
            }
            if (ms) {
               f = ast_read(chan);
               if (!f) {
                  ast_debug(1, "Null frame == hangup() detected\n");
                  res = -1;
                  break;
               }
               if (f->frametype == AST_FRAME_DTMF) {
                  ast_debug(1, "User pressed a key\n");
                  ast_frfree(f);
                  res = 0;
                  break;
               }
               ast_frfree(f);
            } 
         }
      }
   }
   close(fds[0]);
   close(fds[1]);
   
   if (pid > -1)
      kill(pid, SIGKILL);
   if (!res && owriteformat)
      ast_set_write_format(chan, owriteformat);

   return res;
}
static int NBScatplay ( int  fd) [static]

Definition at line 68 of file app_nbscat.c.

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

Referenced by NBScat_exec().

{
   int res;

   res = ast_safe_fork(0);
   if (res < 0) {
      ast_log(LOG_WARNING, "Fork failed\n");
   }

   if (res) {
      return res;
   }

   if (ast_opt_high_priority)
      ast_set_priority(0);

   dup2(fd, STDOUT_FILENO);
   ast_close_fds_above_n(STDERR_FILENO);
   /* Most commonly installed in /usr/local/bin */
   execl(NBSCAT, "nbscat8k", "-d", (char *)NULL);
   execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL);
   fprintf(stderr, "Execute of nbscat8k failed\n");
   _exit(0);
}
static int timed_read ( int  fd,
void *  data,
int  datalen 
) [static]

Definition at line 93 of file app_nbscat.c.

References ast_log(), ast_poll, and LOG_NOTICE.

Referenced by NBScat_exec().

{
   int res;
   struct pollfd fds[1];
   fds[0].fd = fd;
   fds[0].events = POLLIN;
   res = ast_poll(fds, 1, 2000);
   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 unload_module ( void  ) [static]

Definition at line 206 of file app_nbscat.c.

References ast_unregister_application().


Variable Documentation

struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Silly NBS Stream Application" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static]

Definition at line 216 of file app_nbscat.c.

char* app = "NBScat" [static]

Definition at line 66 of file app_nbscat.c.

Definition at line 216 of file app_nbscat.c.