Sat Mar 24 23:26:30 2007

Asterisk developer's documentation


app_nbscat.c File Reference

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

#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 "asterisk.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 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

char * description (void)
 Provides a description of the module.
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
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)
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.

Variables

static char * app = "NBScat"
static char * descrip
 LOCAL_USER_DECL
 STANDARD_LOCAL_USER
static char * synopsis = "Play an NBS local stream"
static char * tdesc = "Silly NBS Stream Application"


Detailed Description

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

Definition in file app_nbscat.c.


Define Documentation

#define AF_LOCAL   AF_UNIX
 

Definition at line 52 of file app_nbscat.c.

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

Definition at line 48 of file app_nbscat.c.

#define NBSCAT   "/usr/bin/nbscat8k"
 

Definition at line 49 of file app_nbscat.c.


Function Documentation

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 226 of file app_nbscat.c.

00227 {
00228    return tdesc;
00229 }

char* key void   ) 
 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 238 of file app_nbscat.c.

References ASTERISK_GPL_KEY.

00239 {
00240    return ASTERISK_GPL_KEY;
00241 }

int load_module void   ) 
 

Initialize the module.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.

Definition at line 221 of file app_nbscat.c.

References ast_register_application(), and NBScat_exec().

00222 {
00223    return ast_register_application(app, NBScat_exec, synopsis, descrip);
00224 }

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

Definition at line 105 of file app_nbscat.c.

References AF_LOCAL, AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_set_write_format(), ast_stopstream(), ast_write(), LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_WARNING, NBScatplay(), offset, timed_read(), and ast_channel::writeformat.

Referenced by load_module().

00106 {
00107    int res=0;
00108    struct localuser *u;
00109    int fds[2];
00110    int ms = -1;
00111    int pid = -1;
00112    int owriteformat;
00113    struct timeval next;
00114    struct ast_frame *f;
00115    struct myframe {
00116       struct ast_frame f;
00117       char offset[AST_FRIENDLY_OFFSET];
00118       short frdata[160];
00119    } myf;
00120    
00121    LOCAL_USER_ADD(u);
00122 
00123    if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) {
00124       ast_log(LOG_WARNING, "Unable to create socketpair\n");
00125       LOCAL_USER_REMOVE(u);
00126       return -1;
00127    }
00128    
00129    ast_stopstream(chan);
00130 
00131    owriteformat = chan->writeformat;
00132    res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
00133    if (res < 0) {
00134       ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
00135       LOCAL_USER_REMOVE(u);
00136       return -1;
00137    }
00138    
00139    res = NBScatplay(fds[1]);
00140    /* Wait 1000 ms first */
00141    next = ast_tvnow();
00142    next.tv_sec += 1;
00143    if (res >= 0) {
00144       pid = res;
00145       /* Order is important -- there's almost always going to be mp3...  we want to prioritize the
00146          user */
00147       for (;;) {
00148          ms = ast_tvdiff_ms(next, ast_tvnow());
00149          if (ms <= 0) {
00150             res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata));
00151             if (res > 0) {
00152                myf.f.frametype = AST_FRAME_VOICE;
00153                myf.f.subclass = AST_FORMAT_SLINEAR;
00154                myf.f.datalen = res;
00155                myf.f.samples = res / 2;
00156                myf.f.mallocd = 0;
00157                myf.f.offset = AST_FRIENDLY_OFFSET;
00158                myf.f.src = __PRETTY_FUNCTION__;
00159                myf.f.delivery.tv_sec = 0;
00160                myf.f.delivery.tv_usec = 0;
00161                myf.f.data = myf.frdata;
00162                if (ast_write(chan, &myf.f) < 0) {
00163                   res = -1;
00164                   break;
00165                }
00166             } else {
00167                ast_log(LOG_DEBUG, "No more mp3\n");
00168                res = 0;
00169                break;
00170             }
00171             next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000));
00172          } else {
00173             ms = ast_waitfor(chan, ms);
00174             if (ms < 0) {
00175                ast_log(LOG_DEBUG, "Hangup detected\n");
00176                res = -1;
00177                break;
00178             }
00179             if (ms) {
00180                f = ast_read(chan);
00181                if (!f) {
00182                   ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
00183                   res = -1;
00184                   break;
00185                }
00186                if (f->frametype == AST_FRAME_DTMF) {
00187                   ast_log(LOG_DEBUG, "User pressed a key\n");
00188                   ast_frfree(f);
00189                   res = 0;
00190                   break;
00191                }
00192                ast_frfree(f);
00193             } 
00194          }
00195       }
00196    }
00197    close(fds[0]);
00198    close(fds[1]);
00199    
00200    if (pid > -1)
00201       kill(pid, SIGKILL);
00202    if (!res && owriteformat)
00203       ast_set_write_format(chan, owriteformat);
00204 
00205    LOCAL_USER_REMOVE(u);
00206 
00207    return res;
00208 }

static int NBScatplay int  fd  )  [static]
 

Definition at line 69 of file app_nbscat.c.

References ast_log(), and LOG_WARNING.

Referenced by NBScat_exec().

00070 {
00071    int res;
00072    int x;
00073    res = fork();
00074    if (res < 0) 
00075       ast_log(LOG_WARNING, "Fork failed\n");
00076    if (res)
00077       return res;
00078    dup2(fd, STDOUT_FILENO);
00079    for (x=0;x<256;x++) {
00080       if (x != STDOUT_FILENO)
00081          close(x);
00082    }
00083    /* Most commonly installed in /usr/local/bin */
00084    execl(NBSCAT, "nbscat8k", "-d", (char *)NULL);
00085    execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL);
00086    ast_log(LOG_WARNING, "Execute of nbscat8k failed\n");
00087    return -1;
00088 }

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

Definition at line 90 of file app_nbscat.c.

References ast_log(), pollfd::events, pollfd::fd, LOG_NOTICE, poll(), and POLLIN.

00091 {
00092    int res;
00093    struct pollfd fds[1];
00094    fds[0].fd = fd;
00095    fds[0].events = POLLIN;
00096    res = poll(fds, 1, 2000);
00097    if (res < 1) {
00098       ast_log(LOG_NOTICE, "Selected timed out/errored out with %d\n", res);
00099       return -1;
00100    }
00101    return read(fd, data, datalen);
00102    
00103 }

int unload_module void   ) 
 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
Zero on success, or non-zero on error.

Definition at line 210 of file app_nbscat.c.

References ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS.

00211 {
00212    int res;
00213 
00214    res = ast_unregister_application(app);
00215 
00216    STANDARD_HANGUP_LOCALUSERS;
00217 
00218    return res;
00219 }

int usecount void   ) 
 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 231 of file app_nbscat.c.

References STANDARD_USECOUNT.

00232 {
00233    int res;
00234    STANDARD_USECOUNT(res);
00235    return res;
00236 }


Variable Documentation

char* app = "NBScat" [static]
 

Definition at line 57 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 61 of file app_nbscat.c.

LOCAL_USER_DECL
 

Definition at line 67 of file app_nbscat.c.

STANDARD_LOCAL_USER
 

Definition at line 65 of file app_nbscat.c.

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

Definition at line 59 of file app_nbscat.c.

char* tdesc = "Silly NBS Stream Application" [static]
 

Definition at line 55 of file app_nbscat.c.


Generated on Sat Mar 24 23:26:31 2007 for Asterisk - the Open Source PBX by  doxygen 1.4.6