#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.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_mp3.c:
Go to the source code of this file.
Defines | |
#define | LOCAL_MPG_123 "/usr/local/bin/mpg123" |
#define | MPG_123 "/usr/bin/mpg123" |
Functions | |
char * | description (void) |
Provides a description of the module. | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
static int | mp3_exec (struct ast_channel *chan, void *data) |
static int | mp3play (char *filename, int fd) |
static int | timed_read (int fd, void *data, int datalen, int timeout) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
static char * | app = "MP3Player" |
static char * | descrip |
LOCAL_USER_DECL | |
STANDARD_LOCAL_USER | |
static char * | synopsis = "Play an MP3 file or stream" |
static char * | tdesc = "Silly MP3 Application" |
Definition in file app_mp3.c.
|
|
|
|
|
Provides a description of the module.
Definition at line 245 of file app_mp3.c. 00246 { 00247 return tdesc; 00248 }
|
|
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 257 of file app_mp3.c. References ASTERISK_GPL_KEY. 00258 { 00259 return ASTERISK_GPL_KEY; 00260 }
|
|
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 240 of file app_mp3.c. References ast_register_application(), and mp3_exec(). 00241 { 00242 return ast_register_application(app, mp3_exec, synopsis, descrip); 00243 }
|
|
Definition at line 115 of file app_mp3.c. References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_set_write_format(), ast_stopstream(), ast_strlen_zero(), ast_write(), LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_WARNING, mp3play(), offset, timed_read(), and ast_channel::writeformat. Referenced by load_module(). 00116 { 00117 int res=0; 00118 struct localuser *u; 00119 int fds[2]; 00120 int ms = -1; 00121 int pid = -1; 00122 int owriteformat; 00123 int timeout = 2000; 00124 struct timeval next; 00125 struct ast_frame *f; 00126 struct myframe { 00127 struct ast_frame f; 00128 char offset[AST_FRIENDLY_OFFSET]; 00129 short frdata[160]; 00130 } myf; 00131 00132 if (ast_strlen_zero(data)) { 00133 ast_log(LOG_WARNING, "MP3 Playback requires an argument (filename)\n"); 00134 return -1; 00135 } 00136 00137 LOCAL_USER_ADD(u); 00138 00139 if (pipe(fds)) { 00140 ast_log(LOG_WARNING, "Unable to create pipe\n"); 00141 LOCAL_USER_REMOVE(u); 00142 return -1; 00143 } 00144 00145 ast_stopstream(chan); 00146 00147 owriteformat = chan->writeformat; 00148 res = ast_set_write_format(chan, AST_FORMAT_SLINEAR); 00149 if (res < 0) { 00150 ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); 00151 LOCAL_USER_REMOVE(u); 00152 return -1; 00153 } 00154 00155 res = mp3play((char *)data, fds[1]); 00156 if (!strncasecmp((char *)data, "http://", 7)) { 00157 timeout = 10000; 00158 } 00159 /* Wait 1000 ms first */ 00160 next = ast_tvnow(); 00161 next.tv_sec += 1; 00162 if (res >= 0) { 00163 pid = res; 00164 /* Order is important -- there's almost always going to be mp3... we want to prioritize the 00165 user */ 00166 for (;;) { 00167 ms = ast_tvdiff_ms(next, ast_tvnow()); 00168 if (ms <= 0) { 00169 res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata), timeout); 00170 if (res > 0) { 00171 myf.f.frametype = AST_FRAME_VOICE; 00172 myf.f.subclass = AST_FORMAT_SLINEAR; 00173 myf.f.datalen = res; 00174 myf.f.samples = res / 2; 00175 myf.f.mallocd = 0; 00176 myf.f.offset = AST_FRIENDLY_OFFSET; 00177 myf.f.src = __PRETTY_FUNCTION__; 00178 myf.f.delivery.tv_sec = 0; 00179 myf.f.delivery.tv_usec = 0; 00180 myf.f.data = myf.frdata; 00181 if (ast_write(chan, &myf.f) < 0) { 00182 res = -1; 00183 break; 00184 } 00185 } else { 00186 ast_log(LOG_DEBUG, "No more mp3\n"); 00187 res = 0; 00188 break; 00189 } 00190 next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000)); 00191 } else { 00192 ms = ast_waitfor(chan, ms); 00193 if (ms < 0) { 00194 ast_log(LOG_DEBUG, "Hangup detected\n"); 00195 res = -1; 00196 break; 00197 } 00198 if (ms) { 00199 f = ast_read(chan); 00200 if (!f) { 00201 ast_log(LOG_DEBUG, "Null frame == hangup() detected\n"); 00202 res = -1; 00203 break; 00204 } 00205 if (f->frametype == AST_FRAME_DTMF) { 00206 ast_log(LOG_DEBUG, "User pressed a key\n"); 00207 ast_frfree(f); 00208 res = 0; 00209 break; 00210 } 00211 ast_frfree(f); 00212 } 00213 } 00214 } 00215 } 00216 close(fds[0]); 00217 close(fds[1]); 00218 00219 if (pid > -1) 00220 kill(pid, SIGKILL); 00221 if (!res && owriteformat) 00222 ast_set_write_format(chan, owriteformat); 00223 00224 LOCAL_USER_REMOVE(u); 00225 00226 return res; 00227 }
|
|
Definition at line 65 of file app_mp3.c. References ast_log(), and LOG_WARNING. Referenced by mp3_exec(). 00066 { 00067 int res; 00068 int x; 00069 res = fork(); 00070 if (res < 0) 00071 ast_log(LOG_WARNING, "Fork failed\n"); 00072 if (res) 00073 return res; 00074 dup2(fd, STDOUT_FILENO); 00075 for (x=0;x<256;x++) { 00076 if (x != STDOUT_FILENO) 00077 close(x); 00078 } 00079 /* Execute mpg123, but buffer if it's a net connection */ 00080 if (!strncasecmp(filename, "http://", 7)) { 00081 /* Most commonly installed in /usr/local/bin */ 00082 execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00083 /* But many places has it in /usr/bin */ 00084 execl(MPG_123, "mpg123", "-q", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00085 /* As a last-ditch effort, try to use PATH */ 00086 execlp("mpg123", "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00087 } 00088 else { 00089 /* Most commonly installed in /usr/local/bin */ 00090 execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00091 /* But many places has it in /usr/bin */ 00092 execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00093 /* As a last-ditch effort, try to use PATH */ 00094 execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00095 } 00096 ast_log(LOG_WARNING, "Execute of mpg123 failed\n"); 00097 return -1; 00098 }
|
|
Definition at line 100 of file app_mp3.c. References ast_log(), pollfd::events, pollfd::fd, LOG_NOTICE, poll(), and POLLIN. Referenced by mp3_exec(), and NBScat_exec(). 00101 { 00102 int res; 00103 struct pollfd fds[1]; 00104 fds[0].fd = fd; 00105 fds[0].events = POLLIN; 00106 res = poll(fds, 1, timeout); 00107 if (res < 1) { 00108 ast_log(LOG_NOTICE, "Poll timed out/errored out with %d\n", res); 00109 return -1; 00110 } 00111 return read(fd, data, datalen); 00112 00113 }
|
|
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 229 of file app_mp3.c. References ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS. 00230 { 00231 int res; 00232 00233 res = ast_unregister_application(app); 00234 00235 STANDARD_HANGUP_LOCALUSERS; 00236 00237 return res; 00238 }
|
|
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 250 of file app_mp3.c. References STANDARD_USECOUNT. 00251 { 00252 int res; 00253 STANDARD_USECOUNT(res); 00254 return res; 00255 }
|
|
|
|
Initial value: " MP3Player(location) Executes mpg123 to play the given location,\n" "which typically would be a filename or a URL. User can exit by pressing\n" "any key on the dialpad, or by hanging up." |
|
|
|
|
|
|
|
|