#include "asterisk.h"
#include <signal.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/capability.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"
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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } |
static char * | app = "ICES" |
static const 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 237 of file app_ices.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 237 of file app_ices.c.
static int ices_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 130 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().
00131 { 00132 int res = 0; 00133 int fds[2]; 00134 int ms = -1; 00135 int pid = -1; 00136 int flags; 00137 int oreadformat; 00138 struct timeval last; 00139 struct ast_frame *f; 00140 char filename[256]=""; 00141 char *c; 00142 00143 if (ast_strlen_zero(data)) { 00144 ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n"); 00145 return -1; 00146 } 00147 00148 last = ast_tv(0, 0); 00149 00150 if (pipe(fds)) { 00151 ast_log(LOG_WARNING, "Unable to create pipe\n"); 00152 return -1; 00153 } 00154 flags = fcntl(fds[1], F_GETFL); 00155 fcntl(fds[1], F_SETFL, flags | O_NONBLOCK); 00156 00157 ast_stopstream(chan); 00158 00159 if (chan->_state != AST_STATE_UP) 00160 res = ast_answer(chan); 00161 00162 if (res) { 00163 close(fds[0]); 00164 close(fds[1]); 00165 ast_log(LOG_WARNING, "Answer failed!\n"); 00166 return -1; 00167 } 00168 00169 oreadformat = chan->readformat; 00170 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00171 if (res < 0) { 00172 close(fds[0]); 00173 close(fds[1]); 00174 ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); 00175 return -1; 00176 } 00177 if (((char *)data)[0] == '/') 00178 ast_copy_string(filename, (char *) data, sizeof(filename)); 00179 else 00180 snprintf(filename, sizeof(filename), "%s/%s", ast_config_AST_CONFIG_DIR, (char *)data); 00181 /* Placeholder for options */ 00182 c = strchr(filename, '|'); 00183 if (c) 00184 *c = '\0'; 00185 res = icesencode(filename, fds[0]); 00186 if (res >= 0) { 00187 pid = res; 00188 for (;;) { 00189 /* Wait for audio, and stream */ 00190 ms = ast_waitfor(chan, -1); 00191 if (ms < 0) { 00192 ast_debug(1, "Hangup detected\n"); 00193 res = -1; 00194 break; 00195 } 00196 f = ast_read(chan); 00197 if (!f) { 00198 ast_debug(1, "Null frame == hangup() detected\n"); 00199 res = -1; 00200 break; 00201 } 00202 if (f->frametype == AST_FRAME_VOICE) { 00203 res = write(fds[1], f->data, f->datalen); 00204 if (res < 0) { 00205 if (errno != EAGAIN) { 00206 ast_log(LOG_WARNING, "Write failed to pipe: %s\n", strerror(errno)); 00207 res = -1; 00208 ast_frfree(f); 00209 break; 00210 } 00211 } 00212 } 00213 ast_frfree(f); 00214 } 00215 } 00216 close(fds[0]); 00217 close(fds[1]); 00218 00219 if (pid > -1) 00220 kill(pid, SIGKILL); 00221 if (!res && oreadformat) 00222 ast_set_read_format(chan, oreadformat); 00223 00224 return res; 00225 }
static int icesencode | ( | char * | filename, | |
int | fd | |||
) | [static] |
Definition at line 69 of file app_ices.c.
References ast_debug, ast_log(), ast_opt_high_priority, ast_set_priority(), LOG_WARNING, path_BIN, and path_LOCAL.
Referenced by ices_exec().
00070 { 00071 int res; 00072 int x; 00073 sigset_t fullset, oldset; 00074 #ifdef HAVE_CAP 00075 cap_t cap; 00076 #endif 00077 00078 sigfillset(&fullset); 00079 pthread_sigmask(SIG_BLOCK, &fullset, &oldset); 00080 00081 res = fork(); 00082 if (res < 0) 00083 ast_log(LOG_WARNING, "Fork failed\n"); 00084 if (res) { 00085 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 00086 return res; 00087 } 00088 00089 /* Stop ignoring PIPE */ 00090 signal(SIGPIPE, SIG_DFL); 00091 pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); 00092 00093 #ifdef HAVE_CAP 00094 cap = cap_from_text("cap_net_admin-eip"); 00095 00096 if (cap_set_proc(cap)) { 00097 /* Careful with order! Logging cannot happen after we close FDs */ 00098 ast_log(LOG_WARNING, "Unable to remove capabilities.\n"); 00099 } 00100 cap_free(cap); 00101 #endif 00102 00103 if (ast_opt_high_priority) 00104 ast_set_priority(0); 00105 dup2(fd, STDIN_FILENO); 00106 for (x=STDERR_FILENO + 1;x<1024;x++) { 00107 if ((x != STDIN_FILENO) && (x != STDOUT_FILENO)) 00108 close(x); 00109 } 00110 00111 /* Most commonly installed in /usr/local/bin 00112 * But many places has it in /usr/bin 00113 * As a last-ditch effort, try to use PATH 00114 */ 00115 execl(path_LOCAL "ices2", "ices", filename, (char *)NULL); 00116 execl(path_BIN "ices2", "ices", filename, (char *)NULL); 00117 execlp("ices2", "ices", filename, (char *)NULL); 00118 00119 ast_debug(1, "Couldn't find ices version 2, attempting to use ices version 1."); 00120 00121 execl(path_LOCAL "ices", "ices", filename, (char *)NULL); 00122 execl(path_BIN "ices", "ices", filename, (char *)NULL); 00123 execlp("ices", "ices", filename, (char *)NULL); 00124 00125 ast_log(LOG_WARNING, "Execute of ices failed, could not find command.\n"); 00126 close(fd); 00127 _exit(0); 00128 }
static int load_module | ( | void | ) | [static] |
Definition at line 232 of file app_ices.c.
References ast_register_application, and ices_exec().
00233 { 00234 return ast_register_application(app, ices_exec, synopsis, descrip); 00235 }
static int unload_module | ( | void | ) | [static] |
Definition at line 227 of file app_ices.c.
References ast_unregister_application().
00228 { 00229 return ast_unregister_application(app); 00230 }
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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 237 of file app_ices.c.
char* app = "ICES" [static] |
Definition at line 57 of file app_ices.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 237 of file app_ices.c.
char* descrip [static] |
Definition at line 61 of file app_ices.c.
char* synopsis = "Encode and stream using 'ices'" [static] |
Definition at line 59 of file app_ices.c.