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