Mon Mar 20 08:20:15 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

app_ices.c File Reference

Stream to an icecast server via ICES (see contrib/asterisk-ices.xml). More...

#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <errno.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"

Go to the source code of this file.

Defines

#define ICES   "/usr/bin/ices"
#define LOCAL_ICES   "/usr/local/bin/ices"

Functions

char * description (void)
 Provides a description of the module.
int ices_exec (struct ast_channel *chan, void *data)
int icesencode (char *filename, int fd)
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.

Variables

char * app = "ICES"
char * descrip
 LOCAL_USER_DECL
 STANDARD_LOCAL_USER
char * synopsis = "Encode and stream using 'ices'"
char * tdesc = "Encode and Stream via icecast and ices"


Detailed Description

Stream to an icecast server via ICES (see contrib/asterisk-ices.xml).

Definition in file app_ices.c.


Define Documentation

#define ICES   "/usr/bin/ices"
 

Definition at line 48 of file app_ices.c.

Referenced by icesencode().

#define LOCAL_ICES   "/usr/local/bin/ices"
 

Definition at line 49 of file app_ices.c.

Referenced by icesencode().


Function Documentation

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 210 of file app_ices.c.

00211 {
00212    return tdesc;
00213 }

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

Definition at line 90 of file app_ices.c.

References ast_channel::_state, ast_answer(), ast_config_AST_CONFIG_DIR, AST_FORMAT_SLINEAR, ast_frfree(), ast_log(), ast_read(), ast_set_read_format(), ast_stopstream(), ast_strlen_zero(), ast_waitfor(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, icesencode(), LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_DEBUG, LOG_WARNING, and ast_channel::readformat.

Referenced by load_module().

00091 {
00092    int res=0;
00093    struct localuser *u;
00094    int fds[2];
00095    int ms = -1;
00096    int pid = -1;
00097    int flags;
00098    int oreadformat;
00099    struct timeval last;
00100    struct ast_frame *f;
00101    char filename[256]="";
00102    char *c;
00103 
00104    if (ast_strlen_zero(data)) {
00105       ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n");
00106       return -1;
00107    }
00108 
00109    LOCAL_USER_ADD(u);
00110    
00111    last = ast_tv(0, 0);
00112    
00113    if (pipe(fds)) {
00114       ast_log(LOG_WARNING, "Unable to create pipe\n");
00115       LOCAL_USER_REMOVE(u);
00116       return -1;
00117    }
00118    flags = fcntl(fds[1], F_GETFL);
00119    fcntl(fds[1], F_SETFL, flags | O_NONBLOCK);
00120    
00121    ast_stopstream(chan);
00122 
00123    if (chan->_state != AST_STATE_UP)
00124       res = ast_answer(chan);
00125       
00126    if (res) {
00127       close(fds[0]);
00128       close(fds[1]);
00129       ast_log(LOG_WARNING, "Answer failed!\n");
00130       LOCAL_USER_REMOVE(u);
00131       return -1;
00132    }
00133 
00134    oreadformat = chan->readformat;
00135    res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
00136    if (res < 0) {
00137       close(fds[0]);
00138       close(fds[1]);
00139       ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
00140       LOCAL_USER_REMOVE(u);
00141       return -1;
00142    }
00143    if (((char *)data)[0] == '/')
00144       strncpy(filename, (char *)data, sizeof(filename) - 1);
00145    else
00146       snprintf(filename, sizeof(filename), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, (char *)data);
00147    /* Placeholder for options */    
00148    c = strchr(filename, '|');
00149    if (c)
00150       *c = '\0';  
00151    res = icesencode(filename, fds[0]);
00152    close(fds[0]);
00153    if (res >= 0) {
00154       pid = res;
00155       for (;;) {
00156          /* Wait for audio, and stream */
00157          ms = ast_waitfor(chan, -1);
00158          if (ms < 0) {
00159             ast_log(LOG_DEBUG, "Hangup detected\n");
00160             res = -1;
00161             break;
00162          }
00163          f = ast_read(chan);
00164          if (!f) {
00165             ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
00166             res = -1;
00167             break;
00168          }
00169          if (f->frametype == AST_FRAME_VOICE) {
00170             res = write(fds[1], f->data, f->datalen);
00171             if (res < 0) {
00172                if (errno != EAGAIN) {
00173                   ast_log(LOG_WARNING, "Write failed to pipe: %s\n", strerror(errno));
00174                   res = -1;
00175                   break;
00176                }
00177             }
00178          }
00179          ast_frfree(f);
00180       }
00181    }
00182    close(fds[1]);
00183    
00184    if (pid > -1)
00185       kill(pid, SIGKILL);
00186    if (!res && oreadformat)
00187       ast_set_read_format(chan, oreadformat);
00188 
00189    LOCAL_USER_REMOVE(u);
00190 
00191    return res;
00192 }

int icesencode char *  filename,
int  fd
[static]
 

Definition at line 66 of file app_ices.c.

References ast_log(), ICES, LOCAL_ICES, and LOG_WARNING.

Referenced by ices_exec().

00067 {
00068    int res;
00069    int x;
00070    res = fork();
00071    if (res < 0) 
00072       ast_log(LOG_WARNING, "Fork failed\n");
00073    if (res)
00074       return res;
00075    dup2(fd, STDIN_FILENO);
00076    for (x=STDERR_FILENO + 1;x<256;x++) {
00077       if ((x != STDIN_FILENO) && (x != STDOUT_FILENO))
00078          close(x);
00079    }
00080    /* Most commonly installed in /usr/local/bin */
00081    execl(ICES, "ices", filename, (char *)NULL);
00082    /* But many places has it in /usr/bin */
00083    execl(LOCAL_ICES, "ices", filename, (char *)NULL);
00084    /* As a last-ditch effort, try to use PATH */
00085    execlp("ices", "ices", filename, (char *)NULL);
00086    ast_log(LOG_WARNING, "Execute of ices failed\n");
00087    return -1;
00088 }

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 222 of file app_ices.c.

00223 {
00224    return ASTERISK_GPL_KEY;
00225 }

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 205 of file app_ices.c.

References app, ast_register_application(), descrip, ices_exec(), and synopsis.

00206 {
00207    return ast_register_application(app, ices_exec, synopsis, descrip);
00208 }

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 194 of file app_ices.c.

References app, and ast_unregister_application().

00195 {
00196    int res;
00197 
00198    res = ast_unregister_application(app);
00199 
00200    STANDARD_HANGUP_LOCALUSERS;
00201 
00202    return res;
00203 }

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 215 of file app_ices.c.

References STANDARD_USECOUNT.

00216 {
00217    int res;
00218    STANDARD_USECOUNT(res);
00219    return res;
00220 }


Variable Documentation

char* app = "ICES" [static]
 

Definition at line 53 of file app_ices.c.

Referenced by load_module(), and unload_module().

char* descrip [static]
 

Initial value:

 
"  ICES(config.xml) Streams to an icecast server using ices\n"
"(available separately).  A configuration file must be supplied\n"
"for ices (see examples/asterisk-ices.conf). \n"

Definition at line 57 of file app_ices.c.

Referenced by load_module().

LOCAL_USER_DECL
 

Definition at line 64 of file app_ices.c.

STANDARD_LOCAL_USER
 

Definition at line 62 of file app_ices.c.

char* synopsis = "Encode and stream using 'ices'" [static]
 

Definition at line 55 of file app_ices.c.

Referenced by load_module().

char* tdesc = "Encode and Stream via icecast and ices" [static]
 

Definition at line 51 of file app_ices.c.


Generated on Mon Mar 20 08:20:15 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1