#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 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 48 of file app_ices.c. |
|
Definition at line 49 of file app_ices.c. |
|
Provides a description of the module.
Definition at line 210 of file app_ices.c. 00211 { 00212 return tdesc; 00213 }
|
|
Definition at line 90 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, LOG_WARNING, and ast_channel::readformat. Referenced by load_module(). 00091 { 00092 int res=0; 00093 struct localuser *u; 00094 int fds[2]; 00095 int ms = -1; 00096 int pid = -1; 00097 int flags; 00098 int oreadformat; 00099 struct timeval last; 00100 struct ast_frame *f; 00101 char filename[256]=""; 00102 char *c; 00103 00104 if (ast_strlen_zero(data)) { 00105 ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n"); 00106 return -1; 00107 } 00108 00109 LOCAL_USER_ADD(u); 00110 00111 last = ast_tv(0, 0); 00112 00113 if (pipe(fds)) { 00114 ast_log(LOG_WARNING, "Unable to create pipe\n"); 00115 LOCAL_USER_REMOVE(u); 00116 return -1; 00117 } 00118 flags = fcntl(fds[1], F_GETFL); 00119 fcntl(fds[1], F_SETFL, flags | O_NONBLOCK); 00120 00121 ast_stopstream(chan); 00122 00123 if (chan->_state != AST_STATE_UP) 00124 res = ast_answer(chan); 00125 00126 if (res) { 00127 close(fds[0]); 00128 close(fds[1]); 00129 ast_log(LOG_WARNING, "Answer failed!\n"); 00130 LOCAL_USER_REMOVE(u); 00131 return -1; 00132 } 00133 00134 oreadformat = chan->readformat; 00135 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00136 if (res < 0) { 00137 close(fds[0]); 00138 close(fds[1]); 00139 ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); 00140 LOCAL_USER_REMOVE(u); 00141 return -1; 00142 } 00143 if (((char *)data)[0] == '/') 00144 strncpy(filename, (char *)data, sizeof(filename) - 1); 00145 else 00146 snprintf(filename, sizeof(filename), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, (char *)data); 00147 /* Placeholder for options */ 00148 c = strchr(filename, '|'); 00149 if (c) 00150 *c = '\0'; 00151 res = icesencode(filename, fds[0]); 00152 close(fds[0]); 00153 if (res >= 0) { 00154 pid = res; 00155 for (;;) { 00156 /* Wait for audio, and stream */ 00157 ms = ast_waitfor(chan, -1); 00158 if (ms < 0) { 00159 ast_log(LOG_DEBUG, "Hangup detected\n"); 00160 res = -1; 00161 break; 00162 } 00163 f = ast_read(chan); 00164 if (!f) { 00165 ast_log(LOG_DEBUG, "Null frame == hangup() detected\n"); 00166 res = -1; 00167 break; 00168 } 00169 if (f->frametype == AST_FRAME_VOICE) { 00170 res = write(fds[1], f->data, f->datalen); 00171 if (res < 0) { 00172 if (errno != EAGAIN) { 00173 ast_log(LOG_WARNING, "Write failed to pipe: %s\n", strerror(errno)); 00174 res = -1; 00175 break; 00176 } 00177 } 00178 } 00179 ast_frfree(f); 00180 } 00181 } 00182 close(fds[1]); 00183 00184 if (pid > -1) 00185 kill(pid, SIGKILL); 00186 if (!res && oreadformat) 00187 ast_set_read_format(chan, oreadformat); 00188 00189 LOCAL_USER_REMOVE(u); 00190 00191 return res; 00192 }
|
|
Definition at line 66 of file app_ices.c. References ast_log(), and LOG_WARNING. Referenced by ices_exec(). 00067 { 00068 int res; 00069 int x; 00070 res = fork(); 00071 if (res < 0) 00072 ast_log(LOG_WARNING, "Fork failed\n"); 00073 if (res) 00074 return res; 00075 dup2(fd, STDIN_FILENO); 00076 for (x=STDERR_FILENO + 1;x<256;x++) { 00077 if ((x != STDIN_FILENO) && (x != STDOUT_FILENO)) 00078 close(x); 00079 } 00080 /* Most commonly installed in /usr/local/bin */ 00081 execl(ICES, "ices", filename, (char *)NULL); 00082 /* But many places has it in /usr/bin */ 00083 execl(LOCAL_ICES, "ices", filename, (char *)NULL); 00084 /* As a last-ditch effort, try to use PATH */ 00085 execlp("ices", "ices", filename, (char *)NULL); 00086 ast_log(LOG_WARNING, "Execute of ices failed\n"); 00087 return -1; 00088 }
|
|
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 222 of file app_ices.c. References ASTERISK_GPL_KEY. 00223 { 00224 return ASTERISK_GPL_KEY; 00225 }
|
|
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 205 of file app_ices.c. References ast_register_application(), and ices_exec(). 00206 { 00207 return ast_register_application(app, ices_exec, synopsis, descrip); 00208 }
|
|
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 194 of file app_ices.c. References ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS. 00195 { 00196 int res; 00197 00198 res = ast_unregister_application(app); 00199 00200 STANDARD_HANGUP_LOCALUSERS; 00201 00202 return res; 00203 }
|
|
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 215 of file app_ices.c. References STANDARD_USECOUNT. 00216 { 00217 int res; 00218 STANDARD_USECOUNT(res); 00219 return res; 00220 }
|
|
Definition at line 53 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 57 of file app_ices.c. |
|
Definition at line 64 of file app_ices.c. |
|
Definition at line 62 of file app_ices.c. |
|
Definition at line 55 of file app_ices.c. |
|
Definition at line 51 of file app_ices.c. |