#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.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"
Include dependency graph for app_ices.c:
Go to the source code of this file.
Defines | |
#define | ICES "/usr/bin/ices" |
#define | LOCAL_ICES "/usr/local/bin/ices" |
Functions | |
char * | description (void) |
Provides a description of the module. | |
static int | ices_exec (struct ast_channel *chan, void *data) |
static int | icesencode (char *filename, int fd) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
static char * | app = "ICES" |
static char * | descrip |
LOCAL_USER_DECL | |
STANDARD_LOCAL_USER | |
static char * | synopsis = "Encode and stream using 'ices'" |
static char * | tdesc = "Encode and Stream via icecast and ices" |
Definition in file app_ices.c.
|
Definition at line 49 of file app_ices.c. Referenced by icesencode(). |
|
Definition at line 50 of file app_ices.c. Referenced by icesencode(). |
|
Provides a description of the module.
Definition at line 214 of file app_ices.c. References tdesc. 00215 { 00216 return tdesc; 00217 }
|
|
Definition at line 93 of file app_ices.c. References ast_channel::_state, ast_answer(), ast_config_AST_CONFIG_DIR, 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_waitfor(), ast_frame::data, ast_frame::datalen, localuser::flags, ast_frame::frametype, icesencode(), LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_DEBUG, and LOG_WARNING. Referenced by load_module(). 00094 { 00095 int res=0; 00096 struct localuser *u; 00097 int fds[2]; 00098 int ms = -1; 00099 int pid = -1; 00100 int flags; 00101 int oreadformat; 00102 struct timeval last; 00103 struct ast_frame *f; 00104 char filename[256]=""; 00105 char *c; 00106 00107 if (ast_strlen_zero(data)) { 00108 ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n"); 00109 return -1; 00110 } 00111 00112 LOCAL_USER_ADD(u); 00113 00114 last = ast_tv(0, 0); 00115 00116 if (pipe(fds)) { 00117 ast_log(LOG_WARNING, "Unable to create pipe\n"); 00118 LOCAL_USER_REMOVE(u); 00119 return -1; 00120 } 00121 flags = fcntl(fds[1], F_GETFL); 00122 fcntl(fds[1], F_SETFL, flags | O_NONBLOCK); 00123 00124 ast_stopstream(chan); 00125 00126 if (chan->_state != AST_STATE_UP) 00127 res = ast_answer(chan); 00128 00129 if (res) { 00130 close(fds[0]); 00131 close(fds[1]); 00132 ast_log(LOG_WARNING, "Answer failed!\n"); 00133 LOCAL_USER_REMOVE(u); 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 LOCAL_USER_REMOVE(u); 00144 return -1; 00145 } 00146 if (((char *)data)[0] == '/') 00147 strncpy(filename, (char *)data, sizeof(filename) - 1); 00148 else 00149 snprintf(filename, sizeof(filename), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, (char *)data); 00150 /* Placeholder for options */ 00151 c = strchr(filename, '|'); 00152 if (c) 00153 *c = '\0'; 00154 res = icesencode(filename, fds[0]); 00155 close(fds[0]); 00156 if (res >= 0) { 00157 pid = res; 00158 for (;;) { 00159 /* Wait for audio, and stream */ 00160 ms = ast_waitfor(chan, -1); 00161 if (ms < 0) { 00162 ast_log(LOG_DEBUG, "Hangup detected\n"); 00163 res = -1; 00164 break; 00165 } 00166 f = ast_read(chan); 00167 if (!f) { 00168 ast_log(LOG_DEBUG, "Null frame == hangup() detected\n"); 00169 res = -1; 00170 break; 00171 } 00172 if (f->frametype == AST_FRAME_VOICE) { 00173 res = write(fds[1], f->data, f->datalen); 00174 if (res < 0) { 00175 if (errno != EAGAIN) { 00176 ast_log(LOG_WARNING, "Write failed to pipe: %s\n", strerror(errno)); 00177 res = -1; 00178 ast_frfree(f); 00179 break; 00180 } 00181 } 00182 } 00183 ast_frfree(f); 00184 } 00185 } 00186 close(fds[1]); 00187 00188 if (pid > -1) 00189 kill(pid, SIGKILL); 00190 if (!res && oreadformat) 00191 ast_set_read_format(chan, oreadformat); 00192 00193 LOCAL_USER_REMOVE(u); 00194 00195 return res; 00196 }
|
|
Definition at line 67 of file app_ices.c. References ast_log(), ast_set_priority(), ICES, LOCAL_ICES, LOG_WARNING, and option_highpriority. Referenced by ices_exec(). 00068 { 00069 int res; 00070 int x; 00071 res = fork(); 00072 if (res < 0) 00073 ast_log(LOG_WARNING, "Fork failed\n"); 00074 if (res) 00075 return res; 00076 if (option_highpriority) 00077 ast_set_priority(0); 00078 dup2(fd, STDIN_FILENO); 00079 for (x=STDERR_FILENO + 1;x<256;x++) { 00080 if ((x != STDIN_FILENO) && (x != STDOUT_FILENO)) 00081 close(x); 00082 } 00083 /* Most commonly installed in /usr/local/bin */ 00084 execl(ICES, "ices", filename, (char *)NULL); 00085 /* But many places has it in /usr/bin */ 00086 execl(LOCAL_ICES, "ices", filename, (char *)NULL); 00087 /* As a last-ditch effort, try to use PATH */ 00088 execlp("ices", "ices", filename, (char *)NULL); 00089 ast_log(LOG_WARNING, "Execute of ices failed\n"); 00090 return -1; 00091 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 226 of file app_ices.c. References ASTERISK_GPL_KEY. 00227 { 00228 return ASTERISK_GPL_KEY; 00229 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 209 of file app_ices.c. References app, ast_register_application(), descrip, ices_exec(), and synopsis. 00210 { 00211 return ast_register_application(app, ices_exec, synopsis, descrip); 00212 }
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 198 of file app_ices.c. References app, ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS. 00199 { 00200 int res; 00201 00202 res = ast_unregister_application(app); 00203 00204 STANDARD_HANGUP_LOCALUSERS; 00205 00206 return res; 00207 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 219 of file app_ices.c. References STANDARD_USECOUNT. 00220 { 00221 int res; 00222 STANDARD_USECOUNT(res); 00223 return res; 00224 }
|
|
Definition at line 54 of file app_ices.c. |
|
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 examples/asterisk-ices.conf). \n" Definition at line 58 of file app_ices.c. |
|
Definition at line 65 of file app_ices.c. |
|
Definition at line 63 of file app_ices.c. |
|
Definition at line 56 of file app_ices.c. |
|
Definition at line 52 of file app_ices.c. |