#include "asterisk.h"
#include <fcntl.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <signal.h>
#include <sys/capability.h>
#include "asterisk/lock.h"
#include "asterisk/file.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 | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | load_module (void) |
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) |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Silly NBS Stream Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } |
static char * | app = "NBScat" |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static char * | descrip |
static char * | synopsis = "Play an NBS local stream" |
Definition in file app_nbscat.c.
#define AF_LOCAL AF_UNIX |
Definition at line 56 of file app_nbscat.c.
#define LOCAL_NBSCAT "/usr/local/bin/nbscat8k" |
#define NBSCAT "/usr/bin/nbscat8k" |
static void __reg_module | ( | void | ) | [static] |
Definition at line 237 of file app_nbscat.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 237 of file app_nbscat.c.
static int load_module | ( | void | ) | [static] |
Definition at line 232 of file app_nbscat.c.
References ast_register_application, and NBScat_exec().
00233 { 00234 return ast_register_application(app, NBScat_exec, synopsis, descrip); 00235 }
static int NBScat_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 129 of file app_nbscat.c.
References AF_LOCAL, ast_debug, AST_FORMAT_SLINEAR, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree, AST_FRIENDLY_OFFSET, ast_log(), ast_read(), ast_samp2tv(), ast_set_write_format(), ast_stopstream(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_waitfor(), ast_write(), chan, f, LOG_WARNING, NBScatplay(), ast_frame::offset, timed_read(), and ast_channel::writeformat.
Referenced by load_module().
00130 { 00131 int res=0; 00132 int fds[2]; 00133 int ms = -1; 00134 int pid = -1; 00135 int owriteformat; 00136 struct timeval next; 00137 struct ast_frame *f; 00138 struct myframe { 00139 struct ast_frame f; 00140 char offset[AST_FRIENDLY_OFFSET]; 00141 short frdata[160]; 00142 } myf; 00143 00144 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) { 00145 ast_log(LOG_WARNING, "Unable to create socketpair\n"); 00146 return -1; 00147 } 00148 00149 ast_stopstream(chan); 00150 00151 owriteformat = chan->writeformat; 00152 res = ast_set_write_format(chan, AST_FORMAT_SLINEAR); 00153 if (res < 0) { 00154 ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); 00155 return -1; 00156 } 00157 00158 res = NBScatplay(fds[1]); 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)); 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_debug(1, "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_debug(1, "Hangup detected\n"); 00195 res = -1; 00196 break; 00197 } 00198 if (ms) { 00199 f = ast_read(chan); 00200 if (!f) { 00201 ast_debug(1, "Null frame == hangup() detected\n"); 00202 res = -1; 00203 break; 00204 } 00205 if (f->frametype == AST_FRAME_DTMF) { 00206 ast_debug(1, "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 return res; 00225 }
static int NBScatplay | ( | int | fd | ) | [static] |
Definition at line 68 of file app_nbscat.c.
References ast_log(), ast_opt_high_priority, ast_set_priority(), LOCAL_NBSCAT, LOG_WARNING, and NBSCAT.
Referenced by NBScat_exec().
00069 { 00070 int res; 00071 int x; 00072 sigset_t fullset, oldset; 00073 #ifdef HAVE_CAP 00074 cap_t cap; 00075 #endif 00076 00077 sigfillset(&fullset); 00078 pthread_sigmask(SIG_BLOCK, &fullset, &oldset); 00079 00080 res = fork(); 00081 if (res < 0) 00082 ast_log(LOG_WARNING, "Fork failed\n"); 00083 if (res) { 00084 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 00085 return res; 00086 } 00087 signal(SIGPIPE, SIG_DFL); 00088 pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); 00089 00090 #ifdef HAVE_CAP 00091 cap = cap_from_text("cap_net_admin-eip"); 00092 00093 if (cap_set_proc(cap)) { 00094 /* Careful with order! Logging cannot happen after we close FDs */ 00095 ast_log(LOG_WARNING, "Unable to remove capabilities.\n"); 00096 } 00097 cap_free(cap); 00098 #endif 00099 if (ast_opt_high_priority) 00100 ast_set_priority(0); 00101 00102 dup2(fd, STDOUT_FILENO); 00103 for (x = STDERR_FILENO + 1; x < 1024; x++) { 00104 if (x != STDOUT_FILENO) 00105 close(x); 00106 } 00107 /* Most commonly installed in /usr/local/bin */ 00108 execl(NBSCAT, "nbscat8k", "-d", (char *)NULL); 00109 execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL); 00110 ast_log(LOG_WARNING, "Execute of nbscat8k failed\n"); 00111 _exit(0); 00112 }
static int timed_read | ( | int | fd, | |
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 114 of file app_nbscat.c.
References ast_log(), ast_poll, and LOG_NOTICE.
00115 { 00116 int res; 00117 struct pollfd fds[1]; 00118 fds[0].fd = fd; 00119 fds[0].events = POLLIN; 00120 res = ast_poll(fds, 1, 2000); 00121 if (res < 1) { 00122 ast_log(LOG_NOTICE, "Selected timed out/errored out with %d\n", res); 00123 return -1; 00124 } 00125 return read(fd, data, datalen); 00126 00127 }
static int unload_module | ( | void | ) | [static] |
Definition at line 227 of file app_nbscat.c.
References ast_unregister_application().
00228 { 00229 return ast_unregister_application(app); 00230 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Silly NBS Stream Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 237 of file app_nbscat.c.
char* app = "NBScat" [static] |
Definition at line 59 of file app_nbscat.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 237 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 63 of file app_nbscat.c.
char* synopsis = "Play an NBS local stream" [static] |
Definition at line 61 of file app_nbscat.c.