Thu Apr 28 2011 16:56:51

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 <signal.h>
#include <fcntl.h>
#include <sys/time.h>
#include "asterisk/paths.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_ices.c:

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
__MODULE_INFO_SECTION 
__mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Encode and Stream via icecast and ices" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, }
static char * app = "ICES"
static struct ast_module_infoast_module_info = &__mod_info

Detailed Description

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

Author:
Mark Spencer <markster@digium.com>
ExtRef:
ICES - http://www.icecast.org/ices.php

Definition in file app_ices.c.


Define Documentation

#define path_BIN   "/usr/bin/"

Definition at line 67 of file app_ices.c.

Referenced by icesencode().

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

Definition at line 68 of file app_ices.c.

Referenced by icesencode().


Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 214 of file app_ices.c.

static void __unreg_module ( void  ) [static]

Definition at line 214 of file app_ices.c.

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

Definition at line 107 of file app_ices.c.

References ast_channel::_state, ast_answer(), ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_debug, AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_read_format(), AST_STATE_UP, ast_stopstream(), ast_strlen_zero(), ast_tv(), ast_waitfor(), ast_frame::data, ast_frame::datalen, errno, f, ast_flags::flags, ast_frame::frametype, icesencode(), LOG_WARNING, ast_frame::ptr, and ast_channel::readformat.

Referenced by load_module().

{
   int res = 0;
   int fds[2];
   int ms = -1;
   int pid = -1;
   int flags;
   int oreadformat;
   struct timeval last;
   struct ast_frame *f;
   char filename[256]="";
   char *c;

   if (ast_strlen_zero(data)) {
      ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n");
      return -1;
   }
   
   last = ast_tv(0, 0);
   
   if (pipe(fds)) {
      ast_log(LOG_WARNING, "Unable to create pipe\n");
      return -1;
   }
   flags = fcntl(fds[1], F_GETFL);
   fcntl(fds[1], F_SETFL, flags | O_NONBLOCK);
   
   ast_stopstream(chan);

   if (chan->_state != AST_STATE_UP)
      res = ast_answer(chan);
      
   if (res) {
      close(fds[0]);
      close(fds[1]);
      ast_log(LOG_WARNING, "Answer failed!\n");
      return -1;
   }

   oreadformat = chan->readformat;
   res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
   if (res < 0) {
      close(fds[0]);
      close(fds[1]);
      ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
      return -1;
   }
   if (((char *)data)[0] == '/')
      ast_copy_string(filename, (char *) data, sizeof(filename));
   else
      snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_CONFIG_DIR, (char *)data);
   /* Placeholder for options */    
   c = strchr(filename, '|');
   if (c)
      *c = '\0';  
   res = icesencode(filename, fds[0]);
   if (res >= 0) {
      pid = res;
      for (;;) {
         /* Wait for audio, and stream */
         ms = ast_waitfor(chan, -1);
         if (ms < 0) {
            ast_debug(1, "Hangup detected\n");
            res = -1;
            break;
         }
         f = ast_read(chan);
         if (!f) {
            ast_debug(1, "Null frame == hangup() detected\n");
            res = -1;
            break;
         }
         if (f->frametype == AST_FRAME_VOICE) {
            res = write(fds[1], f->data.ptr, f->datalen);
            if (res < 0) {
               if (errno != EAGAIN) {
                  ast_log(LOG_WARNING, "Write failed to pipe: %s\n", strerror(errno));
                  res = -1;
                  ast_frfree(f);
                  break;
               }
            }
         }
         ast_frfree(f);
      }
   }
   close(fds[0]);
   close(fds[1]);

   if (pid > -1)
      kill(pid, SIGKILL);
   if (!res && oreadformat)
      ast_set_read_format(chan, oreadformat);

   return res;
}
static int icesencode ( char *  filename,
int  fd 
) [static]

Definition at line 72 of file app_ices.c.

References ast_close_fds_above_n(), ast_debug, ast_log(), ast_opt_high_priority, ast_safe_fork(), ast_set_priority(), LOG_WARNING, path_BIN, path_LOCAL, and SENTINEL.

Referenced by ices_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, STDIN_FILENO);
   ast_close_fds_above_n(STDERR_FILENO);

   /* Most commonly installed in /usr/local/bin 
    * But many places has it in /usr/bin 
    * As a last-ditch effort, try to use PATH
    */
   execl(path_LOCAL "ices2", "ices", filename, SENTINEL);
   execl(path_BIN "ices2", "ices", filename, SENTINEL);
   execlp("ices2", "ices", filename, SENTINEL);

   ast_debug(1, "Couldn't find ices version 2, attempting to use ices version 1.");

   execl(path_LOCAL "ices", "ices", filename, SENTINEL);
   execl(path_BIN "ices", "ices", filename, SENTINEL);
   execlp("ices", "ices", filename, SENTINEL);

   ast_log(LOG_WARNING, "Execute of ices failed, could not find command.\n");
   close(fd);
   _exit(0);
}
static int load_module ( void  ) [static]

Definition at line 209 of file app_ices.c.

References ast_register_application_xml, and ices_exec().

static int unload_module ( void  ) [static]

Definition at line 204 of file app_ices.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 = "Encode and Stream via icecast and ices" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static]

Definition at line 214 of file app_ices.c.

char* app = "ICES" [static]

Definition at line 70 of file app_ices.c.

Definition at line 214 of file app_ices.c.