Sat Aug 6 00:39:34 2011

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 <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 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 = "361d7bb937402d51e4658efb5b4d76e4" , .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 58 of file app_ices.c.

Referenced by icesencode().

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

Definition at line 59 of file app_ices.c.

Referenced by icesencode().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 253 of file app_ices.c.

static void __unreg_module ( void   )  [static]

Definition at line 253 of file app_ices.c.

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

Definition at line 132 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().

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

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

Definition at line 70 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().

00071 {
00072    int res;
00073    int x;
00074    sigset_t fullset, oldset;
00075 #ifdef HAVE_CAP
00076    cap_t cap;
00077 #endif
00078 
00079    sigfillset(&fullset);
00080    pthread_sigmask(SIG_BLOCK, &fullset, &oldset);
00081 
00082    res = fork();
00083    if (res < 0) 
00084       ast_log(LOG_WARNING, "Fork failed\n");
00085    if (res) {
00086       pthread_sigmask(SIG_SETMASK, &oldset, NULL);
00087       return res;
00088    }
00089 
00090    /* Stop ignoring PIPE */
00091    signal(SIGPIPE, SIG_DFL);
00092    pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);
00093 
00094 #ifdef HAVE_CAP
00095    cap = cap_from_text("cap_net_admin-eip");
00096 
00097    if (cap_set_proc(cap)) {
00098       /* Careful with order! Logging cannot happen after we close FDs */
00099       ast_log(LOG_WARNING, "Unable to remove capabilities.\n");
00100    }
00101    cap_free(cap);
00102 #endif
00103 
00104    if (ast_opt_high_priority)
00105       ast_set_priority(0);
00106    dup2(fd, STDIN_FILENO);
00107    for (x=STDERR_FILENO + 1;x<1024;x++) {
00108       if ((x != STDIN_FILENO) && (x != STDOUT_FILENO))
00109          close(x);
00110    }
00111 
00112    /* Most commonly installed in /usr/local/bin 
00113     * But many places has it in /usr/bin 
00114     * As a last-ditch effort, try to use PATH
00115     */
00116    execl(path_LOCAL "ices2", "ices", filename, (char *)NULL);
00117    execl(path_BIN "ices2", "ices", filename, (char *)NULL);
00118    execlp("ices2", "ices", filename, (char *)NULL);
00119 
00120    if (option_debug)
00121       ast_log(LOG_DEBUG, "Couldn't find ices version 2, attempting to use ices version 1.");
00122 
00123    execl(path_LOCAL "ices", "ices", filename, (char *)NULL);
00124    execl(path_BIN "ices", "ices", filename, (char *)NULL);
00125    execlp("ices", "ices", filename, (char *)NULL);
00126 
00127    ast_log(LOG_WARNING, "Execute of ices failed, could not be found.\n");
00128    close(fd);
00129    _exit(0);
00130 }

static int load_module ( void   )  [static]

Definition at line 248 of file app_ices.c.

References ast_register_application(), and ices_exec().

00249 {
00250    return ast_register_application(app, ices_exec, synopsis, descrip);
00251 }

static int unload_module ( void   )  [static]

Definition at line 237 of file app_ices.c.

References ast_module_user_hangup_all, and ast_unregister_application().

00238 {
00239    int res;
00240 
00241    res = ast_unregister_application(app);
00242 
00243    ast_module_user_hangup_all();
00244 
00245    return res;
00246 }


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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 253 of file app_ices.c.

char* app = "ICES" [static]

Definition at line 61 of file app_ices.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 253 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 65 of file app_ices.c.

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

Definition at line 63 of file app_ices.c.


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