#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/socket.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"
Go to the source code of this file.
Defines | |
#define | AF_LOCAL AF_UNIX |
#define | LOCAL_NBSCAT "/usr/local/bin/nbscat8k" |
#define | NBSCAT "/usr/bin/nbscat8k" |
Functions | |
char * | description (void) |
Provides a description of the module. | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
int | NBScat_exec (struct ast_channel *chan, void *data) |
int | NBScatplay (int fd) |
int | timed_read (int fd, void *data, int datalen) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
char * | app = "NBScat" |
char * | descrip |
LOCAL_USER_DECL | |
STANDARD_LOCAL_USER | |
char * | synopsis = "Play an NBS local stream" |
char * | tdesc = "Silly NBS Stream Application" |
Definition in file app_nbscat.c.
|
Definition at line 52 of file app_nbscat.c. |
|
Definition at line 48 of file app_nbscat.c. Referenced by NBScatplay(). |
|
Definition at line 49 of file app_nbscat.c. Referenced by NBScatplay(). |
|
Provides a description of the module.
Definition at line 226 of file app_nbscat.c. 00227 {
00228 return tdesc;
00229 }
|
|
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 238 of file app_nbscat.c. 00239 {
00240 return ASTERISK_GPL_KEY;
00241 }
|
|
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 221 of file app_nbscat.c. References app, ast_register_application(), descrip, NBScat_exec(), and synopsis. 00222 { 00223 return ast_register_application(app, NBScat_exec, synopsis, descrip); 00224 }
|
|
Definition at line 105 of file app_nbscat.c. References AF_LOCAL, AST_FORMAT_SLINEAR, ast_frfree(), ast_log(), ast_read(), ast_set_write_format(), ast_stopstream(), ast_tvadd(), ast_waitfor(), ast_write(), ast_channel::data, ast_frame::frametype, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_DEBUG, LOG_WARNING, NBScatplay(), timed_read(), and ast_channel::writeformat. Referenced by load_module(). 00106 { 00107 int res=0; 00108 struct localuser *u; 00109 int fds[2]; 00110 int ms = -1; 00111 int pid = -1; 00112 int owriteformat; 00113 struct timeval next; 00114 struct ast_frame *f; 00115 struct myframe { 00116 struct ast_frame f; 00117 char offset[AST_FRIENDLY_OFFSET]; 00118 short frdata[160]; 00119 } myf; 00120 00121 LOCAL_USER_ADD(u); 00122 00123 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) { 00124 ast_log(LOG_WARNING, "Unable to create socketpair\n"); 00125 LOCAL_USER_REMOVE(u); 00126 return -1; 00127 } 00128 00129 ast_stopstream(chan); 00130 00131 owriteformat = chan->writeformat; 00132 res = ast_set_write_format(chan, AST_FORMAT_SLINEAR); 00133 if (res < 0) { 00134 ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); 00135 LOCAL_USER_REMOVE(u); 00136 return -1; 00137 } 00138 00139 res = NBScatplay(fds[1]); 00140 /* Wait 1000 ms first */ 00141 next = ast_tvnow(); 00142 next.tv_sec += 1; 00143 if (res >= 0) { 00144 pid = res; 00145 /* Order is important -- there's almost always going to be mp3... we want to prioritize the 00146 user */ 00147 for (;;) { 00148 ms = ast_tvdiff_ms(next, ast_tvnow()); 00149 if (ms <= 0) { 00150 res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata)); 00151 if (res > 0) { 00152 myf.f.frametype = AST_FRAME_VOICE; 00153 myf.f.subclass = AST_FORMAT_SLINEAR; 00154 myf.f.datalen = res; 00155 myf.f.samples = res / 2; 00156 myf.f.mallocd = 0; 00157 myf.f.offset = AST_FRIENDLY_OFFSET; 00158 myf.f.src = __PRETTY_FUNCTION__; 00159 myf.f.delivery.tv_sec = 0; 00160 myf.f.delivery.tv_usec = 0; 00161 myf.f.data = myf.frdata; 00162 if (ast_write(chan, &myf.f) < 0) { 00163 res = -1; 00164 break; 00165 } 00166 } else { 00167 ast_log(LOG_DEBUG, "No more mp3\n"); 00168 res = 0; 00169 break; 00170 } 00171 next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000)); 00172 } else { 00173 ms = ast_waitfor(chan, ms); 00174 if (ms < 0) { 00175 ast_log(LOG_DEBUG, "Hangup detected\n"); 00176 res = -1; 00177 break; 00178 } 00179 if (ms) { 00180 f = ast_read(chan); 00181 if (!f) { 00182 ast_log(LOG_DEBUG, "Null frame == hangup() detected\n"); 00183 res = -1; 00184 break; 00185 } 00186 if (f->frametype == AST_FRAME_DTMF) { 00187 ast_log(LOG_DEBUG, "User pressed a key\n"); 00188 ast_frfree(f); 00189 res = 0; 00190 break; 00191 } 00192 ast_frfree(f); 00193 } 00194 } 00195 } 00196 } 00197 close(fds[0]); 00198 close(fds[1]); 00199 00200 if (pid > -1) 00201 kill(pid, SIGKILL); 00202 if (!res && owriteformat) 00203 ast_set_write_format(chan, owriteformat); 00204 00205 LOCAL_USER_REMOVE(u); 00206 00207 return res; 00208 }
|
|
Definition at line 69 of file app_nbscat.c. References ast_log(), LOCAL_NBSCAT, LOG_WARNING, and NBSCAT. Referenced by NBScat_exec(). 00070 { 00071 int res; 00072 int x; 00073 res = fork(); 00074 if (res < 0) 00075 ast_log(LOG_WARNING, "Fork failed\n"); 00076 if (res) 00077 return res; 00078 dup2(fd, STDOUT_FILENO); 00079 for (x=0;x<256;x++) { 00080 if (x != STDOUT_FILENO) 00081 close(x); 00082 } 00083 /* Most commonly installed in /usr/local/bin */ 00084 execl(NBSCAT, "nbscat8k", "-d", (char *)NULL); 00085 execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL); 00086 ast_log(LOG_WARNING, "Execute of nbscat8k failed\n"); 00087 return -1; 00088 }
|
|
Definition at line 90 of file app_nbscat.c. References ast_log(), pollfd::events, pollfd::fd, LOG_NOTICE, and poll(). Referenced by mp3_exec(), and NBScat_exec(). 00091 { 00092 int res; 00093 struct pollfd fds[1]; 00094 fds[0].fd = fd; 00095 fds[0].events = POLLIN; 00096 res = poll(fds, 1, 2000); 00097 if (res < 1) { 00098 ast_log(LOG_NOTICE, "Selected timed out/errored out with %d\n", res); 00099 return -1; 00100 } 00101 return read(fd, data, datalen); 00102 00103 }
|
|
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 210 of file app_nbscat.c. References app, and ast_unregister_application(). 00211 { 00212 int res; 00213 00214 res = ast_unregister_application(app); 00215 00216 STANDARD_HANGUP_LOCALUSERS; 00217 00218 return res; 00219 }
|
|
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 231 of file app_nbscat.c. References STANDARD_USECOUNT. 00232 { 00233 int res; 00234 STANDARD_USECOUNT(res); 00235 return res; 00236 }
|
|
Definition at line 57 of file app_nbscat.c. Referenced by load_module(), and unload_module(). |
|
Initial value: " NBScat: Executes nbscat to listen to the local NBS stream.\n" "User can exit by pressing any key\n." Definition at line 61 of file app_nbscat.c. Referenced by load_module(). |
|
Definition at line 67 of file app_nbscat.c. |
|
Definition at line 65 of file app_nbscat.c. |
|
Definition at line 59 of file app_nbscat.c. Referenced by load_module(). |
|
Definition at line 55 of file app_nbscat.c. |