#include "asterisk.h"
#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/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 | 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 | AST_MODFLAG_BUILDSUM, .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 = "f450f61f60e761b3aa089ebed76ca8a5" , .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 55 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 116 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_module_user_add, ast_module_user_remove, ast_read(), ast_samp2tv(), ast_set_write_format(), ast_stopstream(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_waitfor(), ast_write(), f, LOG_DEBUG, LOG_WARNING, NBScatplay(), offset, timed_read(), and ast_channel::writeformat.
Referenced by load_module().
00117 { 00118 int res=0; 00119 struct ast_module_user *u; 00120 int fds[2]; 00121 int ms = -1; 00122 int pid = -1; 00123 int owriteformat; 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 u = ast_module_user_add(chan); 00133 00134 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) { 00135 ast_log(LOG_WARNING, "Unable to create socketpair\n"); 00136 ast_module_user_remove(u); 00137 return -1; 00138 } 00139 00140 ast_stopstream(chan); 00141 00142 owriteformat = chan->writeformat; 00143 res = ast_set_write_format(chan, AST_FORMAT_SLINEAR); 00144 if (res < 0) { 00145 ast_log(LOG_WARNING, "Unable to set write format to signed linear\n"); 00146 ast_module_user_remove(u); 00147 return -1; 00148 } 00149 00150 res = NBScatplay(fds[1]); 00151 /* Wait 1000 ms first */ 00152 next = ast_tvnow(); 00153 next.tv_sec += 1; 00154 if (res >= 0) { 00155 pid = res; 00156 /* Order is important -- there's almost always going to be mp3... we want to prioritize the 00157 user */ 00158 for (;;) { 00159 ms = ast_tvdiff_ms(next, ast_tvnow()); 00160 if (ms <= 0) { 00161 res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata)); 00162 if (res > 0) { 00163 myf.f.frametype = AST_FRAME_VOICE; 00164 myf.f.subclass = AST_FORMAT_SLINEAR; 00165 myf.f.datalen = res; 00166 myf.f.samples = res / 2; 00167 myf.f.mallocd = 0; 00168 myf.f.offset = AST_FRIENDLY_OFFSET; 00169 myf.f.src = __PRETTY_FUNCTION__; 00170 myf.f.delivery.tv_sec = 0; 00171 myf.f.delivery.tv_usec = 0; 00172 myf.f.data = myf.frdata; 00173 if (ast_write(chan, &myf.f) < 0) { 00174 res = -1; 00175 break; 00176 } 00177 } else { 00178 ast_log(LOG_DEBUG, "No more mp3\n"); 00179 res = 0; 00180 break; 00181 } 00182 next = ast_tvadd(next, ast_samp2tv(myf.f.samples, 8000)); 00183 } else { 00184 ms = ast_waitfor(chan, ms); 00185 if (ms < 0) { 00186 ast_log(LOG_DEBUG, "Hangup detected\n"); 00187 res = -1; 00188 break; 00189 } 00190 if (ms) { 00191 f = ast_read(chan); 00192 if (!f) { 00193 ast_log(LOG_DEBUG, "Null frame == hangup() detected\n"); 00194 res = -1; 00195 break; 00196 } 00197 if (f->frametype == AST_FRAME_DTMF) { 00198 ast_log(LOG_DEBUG, "User pressed a key\n"); 00199 ast_frfree(f); 00200 res = 0; 00201 break; 00202 } 00203 ast_frfree(f); 00204 } 00205 } 00206 } 00207 } 00208 close(fds[0]); 00209 close(fds[1]); 00210 00211 if (pid > -1) 00212 kill(pid, SIGKILL); 00213 if (!res && owriteformat) 00214 ast_set_write_format(chan, owriteformat); 00215 00216 ast_module_user_remove(u); 00217 00218 return res; 00219 }
static int NBScatplay | ( | int | fd | ) | [static] |
Definition at line 67 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().
00068 { 00069 int res; 00070 int x; 00071 sigset_t fullset, oldset; 00072 00073 sigfillset(&fullset); 00074 pthread_sigmask(SIG_BLOCK, &fullset, &oldset); 00075 00076 res = fork(); 00077 if (res < 0) 00078 ast_log(LOG_WARNING, "Fork failed\n"); 00079 if (res) { 00080 pthread_sigmask(SIG_SETMASK, &oldset, NULL); 00081 return res; 00082 } 00083 signal(SIGPIPE, SIG_DFL); 00084 pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); 00085 00086 if (ast_opt_high_priority) 00087 ast_set_priority(0); 00088 00089 dup2(fd, STDOUT_FILENO); 00090 for (x = STDERR_FILENO + 1; x < 1024; x++) { 00091 if (x != STDOUT_FILENO) 00092 close(x); 00093 } 00094 /* Most commonly installed in /usr/local/bin */ 00095 execl(NBSCAT, "nbscat8k", "-d", (char *)NULL); 00096 execl(LOCAL_NBSCAT, "nbscat8k", "-d", (char *)NULL); 00097 ast_log(LOG_WARNING, "Execute of nbscat8k failed\n"); 00098 _exit(0); 00099 }
static int timed_read | ( | int | fd, | |
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 101 of file app_nbscat.c.
References ast_log(), pollfd::events, pollfd::fd, LOG_NOTICE, poll(), and POLLIN.
00102 { 00103 int res; 00104 struct pollfd fds[1]; 00105 fds[0].fd = fd; 00106 fds[0].events = POLLIN; 00107 res = poll(fds, 1, 2000); 00108 if (res < 1) { 00109 ast_log(LOG_NOTICE, "Selected timed out/errored out with %d\n", res); 00110 return -1; 00111 } 00112 return read(fd, data, datalen); 00113 00114 }
static int unload_module | ( | void | ) | [static] |
Definition at line 221 of file app_nbscat.c.
References ast_module_user_hangup_all, and ast_unregister_application().
00222 { 00223 int res; 00224 00225 res = ast_unregister_application(app); 00226 00227 ast_module_user_hangup_all(); 00228 00229 return res; 00230 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .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 = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 237 of file app_nbscat.c.
char* app = "NBScat" [static] |
Definition at line 58 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 62 of file app_nbscat.c.
char* synopsis = "Play an NBS local stream" [static] |
Definition at line 60 of file app_nbscat.c.