#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 "asterisk/options.h"
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 248 of file app_mp3.c. 00249 { 00250 return tdesc; 00251 }
|
|
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 260 of file app_mp3.c. References ASTERISK_GPL_KEY. 00261 { 00262 return ASTERISK_GPL_KEY; 00263 }
|
|
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 243 of file app_mp3.c. References ast_register_application(), and mp3_exec(). 00244 { 00245 return ast_register_application(app, mp3_exec, synopsis, descrip); 00246 }
|
|
Definition at line 118 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(). 00119 { 00120 int res=0; 00121 struct localuser *u; 00122 int fds[2]; 00123 int ms = -1; 00124 int pid = -1; 00125 int owriteformat; 00126 int timeout = 2000; 00127 struct timeval next; 00128 struct ast_frame *f; 00129 struct myframe { 00130 struct ast_frame f; 00131 char offset[AST_FRIENDLY_OFFSET]; 00132 short frdata[160]; 00133 } myf; 00134 00135 if (ast_strlen_zero(data)) { 00136 ast_log(LOG_WARNING, "MP3 Playback requires an argument (filename)\n"); 00137 return -1; 00138 } 00139 00140 LOCAL_USER_ADD(u); 00141 00142 if (pipe(fds)) { 00143 ast_log(LOG_WARNING, "Unable to create pipe\n"); 00144 LOCAL_USER_REMOVE(u); 00145 return -1; 00146 } 00147 00148 ast_stopstream(chan); 00149 00150 owriteformat = chan->writeformat; 00151 res = ast_set_write_format(chan, AST_FORMAT_SLINEAR); 00152 if (res < 0) { 00153 ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); 00154 LOCAL_USER_REMOVE(u); 00155 return -1; 00156 } 00157 00158 res = mp3play((char *)data, fds[1]); 00159 if (!strncasecmp((char *)data, "http://", 7)) { 00160 timeout = 10000; 00161 } 00162 /* Wait 1000 ms first */ 00163 next = ast_tvnow(); 00164 next.tv_sec += 1; 00165 if (res >= 0) { 00166 pid = res; 00167 /* Order is important -- there's almost always going to be mp3... we want to prioritize the 00168 user */ 00169 for (;;) { 00170 ms = ast_tvdiff_ms(next, ast_tvnow()); 00171 if (ms <= 0) { 00172 res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata), timeout); 00173 if (res > 0) { 00174 myf.f.frametype = AST_FRAME_VOICE; 00175 myf.f.subclass = AST_FORMAT_SLINEAR; 00176 myf.f.datalen = res; 00177 myf.f.samples = res / 2; 00178 myf.f.mallocd = 0; 00179 myf.f.offset = AST_FRIENDLY_OFFSET; 00180 myf.f.src = __PRETTY_FUNCTION__; 00181 myf.f.delivery.tv_sec = 0; 00182 myf.f.delivery.tv_usec = 0; 00183 myf.f.data = myf.frdata; 00184 if (ast_write(chan, &myf.f) < 0) { 00185 res = -1; 00186 break; 00187 } 00188 } else { 00189 ast_log(LOG_DEBUG, "No more mp3\n"); 00190 res = 0; 00191 break; 00192 } 00193 next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000)); 00194 } else { 00195 ms = ast_waitfor(chan, ms); 00196 if (ms < 0) { 00197 ast_log(LOG_DEBUG, "Hangup detected\n"); 00198 res = -1; 00199 break; 00200 } 00201 if (ms) { 00202 f = ast_read(chan); 00203 if (!f) { 00204 ast_log(LOG_DEBUG, "Null frame == hangup() detected\n"); 00205 res = -1; 00206 break; 00207 } 00208 if (f->frametype == AST_FRAME_DTMF) { 00209 ast_log(LOG_DEBUG, "User pressed a key\n"); 00210 ast_frfree(f); 00211 res = 0; 00212 break; 00213 } 00214 ast_frfree(f); 00215 } 00216 } 00217 } 00218 } 00219 close(fds[0]); 00220 close(fds[1]); 00221 00222 if (pid > -1) 00223 kill(pid, SIGKILL); 00224 if (!res && owriteformat) 00225 ast_set_write_format(chan, owriteformat); 00226 00227 LOCAL_USER_REMOVE(u); 00228 00229 return res; 00230 }
|
|
Definition at line 66 of file app_mp3.c. References ast_log(), ast_set_priority(), LOG_WARNING, and option_highpriority. Referenced by mp3_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 if (option_highpriority) 00076 ast_set_priority(0); 00077 dup2(fd, STDOUT_FILENO); 00078 for (x=0;x<256;x++) { 00079 if (x != STDOUT_FILENO) 00080 close(x); 00081 } 00082 /* Execute mpg123, but buffer if it's a net connection */ 00083 if (!strncasecmp(filename, "http://", 7)) { 00084 /* Most commonly installed in /usr/local/bin */ 00085 execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00086 /* But many places has it in /usr/bin */ 00087 execl(MPG_123, "mpg123", "-q", "-s", "-b", "1024","-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00088 /* As a last-ditch effort, try to use PATH */ 00089 execlp("mpg123", "mpg123", "-q", "-s", "-b", "1024", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00090 } 00091 else { 00092 /* Most commonly installed in /usr/local/bin */ 00093 execl(MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00094 /* But many places has it in /usr/bin */ 00095 execl(LOCAL_MPG_123, "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00096 /* As a last-ditch effort, try to use PATH */ 00097 execlp("mpg123", "mpg123", "-q", "-s", "-f", "8192", "--mono", "-r", "8000", filename, (char *)NULL); 00098 } 00099 ast_log(LOG_WARNING, "Execute of mpg123 failed\n"); 00100 return -1; 00101 }
|
|
Definition at line 103 of file app_mp3.c. References ast_log(), pollfd::events, pollfd::fd, LOG_NOTICE, poll(), and POLLIN. Referenced by mp3_exec(), and NBScat_exec(). 00104 { 00105 int res; 00106 struct pollfd fds[1]; 00107 fds[0].fd = fd; 00108 fds[0].events = POLLIN; 00109 res = poll(fds, 1, timeout); 00110 if (res < 1) { 00111 ast_log(LOG_NOTICE, "Poll timed out/errored out with %d\n", res); 00112 return -1; 00113 } 00114 return read(fd, data, datalen); 00115 00116 }
|
|
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 232 of file app_mp3.c. References ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS. 00233 { 00234 int res; 00235 00236 res = ast_unregister_application(app); 00237 00238 STANDARD_HANGUP_LOCALUSERS; 00239 00240 return res; 00241 }
|
|
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 253 of file app_mp3.c. References STANDARD_USECOUNT. 00254 { 00255 int res; 00256 STANDARD_USECOUNT(res); 00257 return res; 00258 }
|
|
|
|
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." |
|
|
|
|
|
|
|
|