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