Wed Mar 4 19:58:17 2009

Asterisk developer's documentation


app_ices.c File Reference

Stream to an icecast server via ICES (see contrib/asterisk-ices.xml). 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 <errno.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 path_BIN   "/usr/bin/"
#define path_LOCAL   "/usr/local/bin/"

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int ices_exec (struct ast_channel *chan, void *data)
static int icesencode (char *filename, int fd)
static int load_module (void)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Encode and Stream via icecast and ices" , .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 = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, }
static char * app = "ICES"
static const struct ast_module_infoast_module_info = &__mod_info
static char * descrip
static char * synopsis = "Encode and stream using 'ices'"


Detailed Description

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

Author:
Mark Spencer <markster@digium.com>

Definition in file app_ices.c.


Define Documentation

#define path_BIN   "/usr/bin/"

Definition at line 51 of file app_ices.c.

Referenced by icesencode().

#define path_LOCAL   "/usr/local/bin/"

Definition at line 52 of file app_ices.c.

Referenced by icesencode().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 233 of file app_ices.c.

static void __unreg_module ( void   )  [static]

Definition at line 233 of file app_ices.c.

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

Definition at line 112 of file app_ices.c.

References ast_channel::_state, ast_answer(), ast_config_AST_CONFIG_DIR, ast_copy_string(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_module_user_add, ast_module_user_remove, ast_read(), ast_set_read_format(), AST_STATE_UP, ast_stopstream(), ast_strlen_zero(), ast_tv(), ast_waitfor(), errno, f, icesencode(), LOG_DEBUG, LOG_WARNING, and ast_channel::readformat.

Referenced by load_module().

00113 {
00114    int res=0;
00115    struct ast_module_user *u;
00116    int fds[2];
00117    int ms = -1;
00118    int pid = -1;
00119    int flags;
00120    int oreadformat;
00121    struct timeval last;
00122    struct ast_frame *f;
00123    char filename[256]="";
00124    char *c;
00125 
00126    if (ast_strlen_zero(data)) {
00127       ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n");
00128       return -1;
00129    }
00130 
00131    u = ast_module_user_add(chan);
00132    
00133    last = ast_tv(0, 0);
00134    
00135    if (pipe(fds)) {
00136       ast_log(LOG_WARNING, "Unable to create pipe\n");
00137       ast_module_user_remove(u);
00138       return -1;
00139    }
00140    flags = fcntl(fds[1], F_GETFL);
00141    fcntl(fds[1], F_SETFL, flags | O_NONBLOCK);
00142    
00143    ast_stopstream(chan);
00144 
00145    if (chan->_state != AST_STATE_UP)
00146       res = ast_answer(chan);
00147       
00148    if (res) {
00149       close(fds[0]);
00150       close(fds[1]);
00151       ast_log(LOG_WARNING, "Answer failed!\n");
00152       ast_module_user_remove(u);
00153       return -1;
00154    }
00155 
00156    oreadformat = chan->readformat;
00157    res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
00158    if (res < 0) {
00159       close(fds[0]);
00160       close(fds[1]);
00161       ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
00162       ast_module_user_remove(u);
00163       return -1;
00164    }
00165    if (((char *)data)[0] == '/')
00166       ast_copy_string(filename, (char *) data, sizeof(filename));
00167    else
00168       snprintf(filename, sizeof(filename), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, (char *)data);
00169    /* Placeholder for options */    
00170    c = strchr(filename, '|');
00171    if (c)
00172       *c = '\0';  
00173    res = icesencode(filename, fds[0]);
00174    if (res >= 0) {
00175       pid = res;
00176       for (;;) {
00177          /* Wait for audio, and stream */
00178          ms = ast_waitfor(chan, -1);
00179          if (ms < 0) {
00180             ast_log(LOG_DEBUG, "Hangup detected\n");
00181             res = -1;
00182             break;
00183          }
00184          f = ast_read(chan);
00185          if (!f) {
00186             ast_log(LOG_DEBUG, "Null frame == hangup() detected\n");
00187             res = -1;
00188             break;
00189          }
00190          if (f->frametype == AST_FRAME_VOICE) {
00191             res = write(fds[1], f->data, f->datalen);
00192             if (res < 0) {
00193                if (errno != EAGAIN) {
00194                   ast_log(LOG_WARNING, "Write failed to pipe: %s\n", strerror(errno));
00195                   res = -1;
00196                   ast_frfree(f);
00197                   break;
00198                }
00199             }
00200          }
00201          ast_frfree(f);
00202       }
00203    }
00204    close(fds[0]);
00205    close(fds[1]);
00206    
00207    if (pid > -1)
00208       kill(pid, SIGKILL);
00209    if (!res && oreadformat)
00210       ast_set_read_format(chan, oreadformat);
00211 
00212    ast_module_user_remove(u);
00213 
00214    return res;
00215 }

static int icesencode ( char *  filename,
int  fd 
) [static]

Definition at line 63 of file app_ices.c.

References ast_log(), ast_opt_high_priority, ast_set_priority(), LOG_DEBUG, LOG_WARNING, option_debug, path_BIN, and path_LOCAL.

Referenced by ices_exec().

00064 {
00065    int res;
00066    int x;
00067    sigset_t fullset, oldset;
00068 
00069    sigfillset(&fullset);
00070    pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
00071 
00072    res = fork();
00073    if (res < 0) 
00074       ast_log(LOG_WARNING, "Fork failed\n");
00075    if (res) {
00076       pthread_sigmask(SIG_SETMASK, &oldset, NULL);
00077       return res;
00078    }
00079 
00080    /* Stop ignoring PIPE */
00081    signal(SIGPIPE, SIG_DFL);
00082    pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
00083 
00084    if (ast_opt_high_priority)
00085       ast_set_priority(0);
00086    dup2(fd, STDIN_FILENO);
00087    for (x=STDERR_FILENO + 1;x<1024;x++) {
00088       if ((x != STDIN_FILENO) && (x != STDOUT_FILENO))
00089          close(x);
00090    }
00091 
00092    /* Most commonly installed in /usr/local/bin 
00093     * But many places has it in /usr/bin 
00094     * As a last-ditch effort, try to use PATH
00095     */
00096    execl(path_LOCAL "ices2", "ices", filename, (char *)NULL);
00097    execl(path_BIN "ices2", "ices", filename, (char *)NULL);
00098    execlp("ices2", "ices", filename, (char *)NULL);
00099 
00100    if (option_debug)
00101       ast_log(LOG_DEBUG, "Couldn't find ices version 2, attempting to use ices version 1.");
00102 
00103    execl(path_LOCAL "ices", "ices", filename, (char *)NULL);
00104    execl(path_BIN "ices", "ices", filename, (char *)NULL);
00105    execlp("ices", "ices", filename, (char *)NULL);
00106 
00107    ast_log(LOG_WARNING, "Execute of ices failed, could not be found.\n");
00108    close(fd);
00109    _exit(0);
00110 }

static int load_module ( void   )  [static]

Definition at line 228 of file app_ices.c.

References ast_register_application(), and ices_exec().

00229 {
00230    return ast_register_application(app, ices_exec, synopsis, descrip);
00231 }

static int unload_module ( void   )  [static]

Definition at line 217 of file app_ices.c.

References ast_module_user_hangup_all, and ast_unregister_application().

00218 {
00219    int res;
00220 
00221    res = ast_unregister_application(app);
00222 
00223    ast_module_user_hangup_all();
00224 
00225    return res;
00226 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Encode and Stream via icecast and ices" , .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 = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, } [static]

Definition at line 233 of file app_ices.c.

char* app = "ICES" [static]

Definition at line 54 of file app_ices.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 233 of file app_ices.c.

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 contrib/asterisk-ices.xml). \n"

Definition at line 58 of file app_ices.c.

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

Definition at line 56 of file app_ices.c.


Generated on Wed Mar 4 19:58:17 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7