Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
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 "asterisk/format_cache.h"
Include dependency graph for app_ices.c:

Go to the source code of this file.

Macros

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

Functions

 AST_MODULE_INFO_STANDARD_DEPRECATED (ASTERISK_GPL_KEY, "Encode and Stream via icecast and ices")
 
static int ices_exec (struct ast_channel *chan, const char *data)
 
static int icesencode (char *filename, int fd)
 
static int load_module (void)
 
static int unload_module (void)
 

Variables

static char * app = "ICES"
 

Detailed Description

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

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

ICES - http://www.icecast.org/ices.php

Definition in file app_ices.c.

Macro Definition Documentation

◆ path_BIN

#define path_BIN   "/usr/bin/"

Definition at line 70 of file app_ices.c.

Referenced by icesencode().

◆ path_LOCAL

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

Definition at line 71 of file app_ices.c.

Referenced by icesencode().

Function Documentation

◆ AST_MODULE_INFO_STANDARD_DEPRECATED()

AST_MODULE_INFO_STANDARD_DEPRECATED ( ASTERISK_GPL_KEY  ,
"Encode and Stream via icecast and ices"   
)

Referenced by load_module().

◆ ices_exec()

static int ices_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 110 of file app_ices.c.

References ao2_bump, ao2_cleanup, ast_answer(), ast_channel_readformat(), ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_debug, ast_fd_set_flags, ast_format_slin, AST_FRAME_VOICE, ast_frfree, ast_log, ast_read(), ast_set_read_format(), AST_STATE_UP, ast_stopstream(), ast_strlen_zero, ast_waitfor(), c, ast_frame::data, ast_frame::datalen, errno, ast_frame::frametype, icesencode(), LOG_WARNING, and ast_frame::ptr.

Referenced by load_module().

111 {
112  int res = 0;
113  int fds[2];
114  int ms = -1;
115  int pid = -1;
116  struct ast_format *oreadformat;
117  struct ast_frame *f;
118  char filename[256]="";
119  char *c;
120 
121  if (ast_strlen_zero(data)) {
122  ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n");
123  return -1;
124  }
125 
126  if (pipe(fds)) {
127  ast_log(LOG_WARNING, "Unable to create pipe\n");
128  return -1;
129  }
130  ast_fd_set_flags(fds[1], O_NONBLOCK);
131 
132  ast_stopstream(chan);
133 
134  if (ast_channel_state(chan) != AST_STATE_UP)
135  res = ast_answer(chan);
136 
137  if (res) {
138  close(fds[0]);
139  close(fds[1]);
140  ast_log(LOG_WARNING, "Answer failed!\n");
141  return -1;
142  }
143 
144  oreadformat = ao2_bump(ast_channel_readformat(chan));
146  if (res < 0) {
147  close(fds[0]);
148  close(fds[1]);
149  ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
150  ao2_cleanup(oreadformat);
151  return -1;
152  }
153  if (((char *)data)[0] == '/')
154  ast_copy_string(filename, (char *) data, sizeof(filename));
155  else
156  snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_CONFIG_DIR, (char *)data);
157  /* Placeholder for options */
158  c = strchr(filename, '|');
159  if (c)
160  *c = '\0';
161  res = icesencode(filename, fds[0]);
162  if (res >= 0) {
163  pid = res;
164  for (;;) {
165  /* Wait for audio, and stream */
166  ms = ast_waitfor(chan, -1);
167  if (ms < 0) {
168  ast_debug(1, "Hangup detected\n");
169  res = -1;
170  break;
171  }
172  f = ast_read(chan);
173  if (!f) {
174  ast_debug(1, "Null frame == hangup() detected\n");
175  res = -1;
176  break;
177  }
178  if (f->frametype == AST_FRAME_VOICE) {
179  res = write(fds[1], f->data.ptr, f->datalen);
180  if (res < 0) {
181  if (errno != EAGAIN) {
182  ast_log(LOG_WARNING, "Write failed to pipe: %s\n", strerror(errno));
183  res = -1;
184  ast_frfree(f);
185  break;
186  }
187  }
188  }
189  ast_frfree(f);
190  }
191  }
192  close(fds[0]);
193  close(fds[1]);
194 
195  if (pid > -1)
196  kill(pid, SIGKILL);
197  if (!res && oreadformat)
198  ast_set_read_format(chan, oreadformat);
199  ao2_cleanup(oreadformat);
200 
201  return res;
202 }
#define LOG_WARNING
Definition: logger.h:274
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4302
ast_channel_state
ast_channel states
Definition: channelstate.h:35
Definition of a media format.
Definition: format.c:43
static int icesencode(char *filename, int fd)
Definition: app_ices.c:75
static struct test_val c
#define ast_strlen_zero(foo)
Definition: strings.h:52
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_fd_set_flags(fd, flags)
Set flags on the given file descriptor.
Definition: utils.h:1009
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151
int errno
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3171
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define ast_frfree(fr)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814
Data structure associated with a single frame of data.
union ast_frame::@263 data
enum ast_frame_type frametype
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ icesencode()

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

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

76 {
77  int res;
78 
79  res = ast_safe_fork(0);
80  if (res < 0)
81  ast_log(LOG_WARNING, "Fork failed\n");
82  if (res) {
83  return res;
84  }
85 
88  dup2(fd, STDIN_FILENO);
89  ast_close_fds_above_n(STDERR_FILENO);
90 
91  /* Most commonly installed in /usr/local/bin
92  * But many places has it in /usr/bin
93  * As a last-ditch effort, try to use PATH
94  */
95  execl(path_LOCAL "ices2", "ices", filename, SENTINEL);
96  execl(path_BIN "ices2", "ices", filename, SENTINEL);
97  execlp("ices2", "ices", filename, SENTINEL);
98 
99  ast_debug(1, "Couldn't find ices version 2, attempting to use ices version 1.\n");
100 
101  execl(path_LOCAL "ices", "ices", filename, SENTINEL);
102  execl(path_BIN "ices", "ices", filename, SENTINEL);
103  execlp("ices", "ices", filename, SENTINEL);
104 
105  ast_log(LOG_WARNING, "Execute of ices failed, could not find command.\n");
106  close(fd);
107  _exit(0);
108 }
#define path_BIN
Definition: app_ices.c:70
#define LOG_WARNING
Definition: logger.h:274
void ast_close_fds_above_n(int n)
Common routine for child processes, to close all fds prior to exec(2)
Definition: main/app.c:3042
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define SENTINEL
Definition: compiler.h:87
int ast_set_priority(int)
We set ourselves to a high priority, that we might pre-empt everything else. If your PBX has heavy ac...
Definition: asterisk.c:1799
int ast_safe_fork(int stop_reaper)
Common routine to safely fork without a chance of a signal handler firing badly in the child...
Definition: main/app.c:3047
#define path_LOCAL
Definition: app_ices.c:71
#define ast_opt_high_priority
Definition: options.h:110

◆ load_module()

static int load_module ( void  )
static

Definition at line 209 of file app_ices.c.

References app, AST_MODULE_INFO_STANDARD_DEPRECATED(), ast_register_application_xml, ASTERISK_GPL_KEY, and ices_exec().

210 {
212 }
static int ices_exec(struct ast_channel *chan, const char *data)
Definition: app_ices.c:110
static char * app
Definition: app_ices.c:73
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 204 of file app_ices.c.

References app, and ast_unregister_application().

205 {
207 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392
static char * app
Definition: app_ices.c:73

Variable Documentation

◆ app

char* app = "ICES"
static

Definition at line 73 of file app_ices.c.

Referenced by load_module(), and unload_module().