#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"
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 , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } |
static char * | app = "ICES" |
static struct ast_module_info * | ast_module_info = &__mod_info |
static char * | descrip |
static char * | synopsis = "Encode and stream using 'ices'" |
Definition in file app_ices.c.
#define path_BIN "/usr/bin/" |
#define path_LOCAL "/usr/local/bin/" |
static void __reg_module | ( | void | ) | [static] |
Definition at line 205 of file app_ices.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 205 of file app_ices.c.
static int ices_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 98 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(), chan, errno, f, ast_flags::flags, icesencode(), LOG_WARNING, and ast_channel::readformat.
Referenced by load_module().
00099 { 00100 int res = 0; 00101 int fds[2]; 00102 int ms = -1; 00103 int pid = -1; 00104 int flags; 00105 int oreadformat; 00106 struct timeval last; 00107 struct ast_frame *f; 00108 char filename[256]=""; 00109 char *c; 00110 00111 if (ast_strlen_zero(data)) { 00112 ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n"); 00113 return -1; 00114 } 00115 00116 last = ast_tv(0, 0); 00117 00118 if (pipe(fds)) { 00119 ast_log(LOG_WARNING, "Unable to create pipe\n"); 00120 return -1; 00121 } 00122 flags = fcntl(fds[1], F_GETFL); 00123 fcntl(fds[1], F_SETFL, flags | O_NONBLOCK); 00124 00125 ast_stopstream(chan); 00126 00127 if (chan->_state != AST_STATE_UP) 00128 res = ast_answer(chan); 00129 00130 if (res) { 00131 close(fds[0]); 00132 close(fds[1]); 00133 ast_log(LOG_WARNING, "Answer failed!\n"); 00134 return -1; 00135 } 00136 00137 oreadformat = chan->readformat; 00138 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00139 if (res < 0) { 00140 close(fds[0]); 00141 close(fds[1]); 00142 ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); 00143 return -1; 00144 } 00145 if (((char *)data)[0] == '/') 00146 ast_copy_string(filename, (char *) data, sizeof(filename)); 00147 else 00148 snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_CONFIG_DIR, (char *)data); 00149 /* Placeholder for options */ 00150 c = strchr(filename, '|'); 00151 if (c) 00152 *c = '\0'; 00153 res = icesencode(filename, fds[0]); 00154 if (res >= 0) { 00155 pid = res; 00156 for (;;) { 00157 /* Wait for audio, and stream */ 00158 ms = ast_waitfor(chan, -1); 00159 if (ms < 0) { 00160 ast_debug(1, "Hangup detected\n"); 00161 res = -1; 00162 break; 00163 } 00164 f = ast_read(chan); 00165 if (!f) { 00166 ast_debug(1, "Null frame == hangup() detected\n"); 00167 res = -1; 00168 break; 00169 } 00170 if (f->frametype == AST_FRAME_VOICE) { 00171 res = write(fds[1], f->data.ptr, f->datalen); 00172 if (res < 0) { 00173 if (errno != EAGAIN) { 00174 ast_log(LOG_WARNING, "Write failed to pipe: %s\n", strerror(errno)); 00175 res = -1; 00176 ast_frfree(f); 00177 break; 00178 } 00179 } 00180 } 00181 ast_frfree(f); 00182 } 00183 } 00184 close(fds[0]); 00185 close(fds[1]); 00186 00187 if (pid > -1) 00188 kill(pid, SIGKILL); 00189 if (!res && oreadformat) 00190 ast_set_read_format(chan, oreadformat); 00191 00192 return res; 00193 }
static int icesencode | ( | char * | filename, | |
int | fd | |||
) | [static] |
Definition at line 63 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().
00064 { 00065 int res; 00066 00067 res = ast_safe_fork(0); 00068 if (res < 0) 00069 ast_log(LOG_WARNING, "Fork failed\n"); 00070 if (res) { 00071 return res; 00072 } 00073 00074 if (ast_opt_high_priority) 00075 ast_set_priority(0); 00076 dup2(fd, STDIN_FILENO); 00077 ast_close_fds_above_n(STDERR_FILENO); 00078 00079 /* Most commonly installed in /usr/local/bin 00080 * But many places has it in /usr/bin 00081 * As a last-ditch effort, try to use PATH 00082 */ 00083 execl(path_LOCAL "ices2", "ices", filename, SENTINEL); 00084 execl(path_BIN "ices2", "ices", filename, SENTINEL); 00085 execlp("ices2", "ices", filename, SENTINEL); 00086 00087 ast_debug(1, "Couldn't find ices version 2, attempting to use ices version 1."); 00088 00089 execl(path_LOCAL "ices", "ices", filename, SENTINEL); 00090 execl(path_BIN "ices", "ices", filename, SENTINEL); 00091 execlp("ices", "ices", filename, SENTINEL); 00092 00093 ast_log(LOG_WARNING, "Execute of ices failed, could not find command.\n"); 00094 close(fd); 00095 _exit(0); 00096 }
static int load_module | ( | void | ) | [static] |
Definition at line 200 of file app_ices.c.
References ast_register_application, and ices_exec().
00201 { 00202 return ast_register_application(app, ices_exec, synopsis, descrip); 00203 }
static int unload_module | ( | void | ) | [static] |
Definition at line 195 of file app_ices.c.
References ast_unregister_application().
00196 { 00197 return ast_unregister_application(app); 00198 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 205 of file app_ices.c.
char* app = "ICES" [static] |
Definition at line 51 of file app_ices.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 205 of file app_ices.c.
char* descrip [static] |
Definition at line 55 of file app_ices.c.
char* synopsis = "Encode and stream using 'ices'" [static] |
Definition at line 53 of file app_ices.c.