#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/app.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/say.h"
#include "asterisk/utils.h"
#include "asterisk/dahdi_compat.h"
Go to the source code of this file.
Defines | |
#define | CONF_SIZE 160 |
Functions | |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Barge in on channel application") | |
static int | careful_write (int fd, unsigned char *data, int len) |
static int | conf_run (struct ast_channel *chan, int confno, int confflags) |
static int | exec (struct ast_channel *chan, void *data, int dahdimode) |
static int | exec_dahdi (struct ast_channel *chan, void *data) |
static int | exec_zap (struct ast_channel *chan, void *data) |
static int | load_module (void) |
static int | unload_module (void) |
Variables | |
static char * | dahdi_app = "DAHDIBarge" |
static char * | dahdi_descrip |
static char * | dahdi_synopsis = "Barge in (monitor) DAHDI channel" |
static char * | zap_app = "ZapBarge" |
static char * | zap_descrip |
static char * | zap_synopsis = "Barge in (monitor) Zap channel" |
Definition in file app_dahdibarge.c.
#define CONF_SIZE 160 |
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"Barge in on channel application" | ||||
) |
static int careful_write | ( | int | fd, | |
unsigned char * | data, | |||
int | len | |||
) | [static] |
Definition at line 84 of file app_dahdibarge.c.
References ast_log(), errno, and LOG_WARNING.
Referenced by conf_play(), and conf_run().
00085 { 00086 int res; 00087 while(len) { 00088 res = write(fd, data, len); 00089 if (res < 1) { 00090 if (errno != EAGAIN) { 00091 ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno)); 00092 return -1; 00093 } else 00094 return 0; 00095 } 00096 len -= res; 00097 data += res; 00098 } 00099 return 0; 00100 }
static int conf_run | ( | struct ast_channel * | chan, | |
int | confno, | |||
int | confflags | |||
) | [static] |
Definition at line 102 of file app_dahdibarge.c.
References AST_FORMAT_ULAW, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree, AST_FRIENDLY_OFFSET, ast_indicate(), ast_log(), ast_read(), ast_set_read_format(), ast_set_write_format(), ast_waitfor_nandfds(), ast_write(), careful_write(), CONF_SIZE, dahdi_chan_name, errno, f, ast_channel::fds, ast_frame::flags, LOG_DEBUG, LOG_WARNING, ast_channel::tech, and ast_channel_tech::type.
Referenced by conf_exec(), exec(), run_station(), sla_station_exec(), and sla_trunk_exec().
00103 { 00104 int fd; 00105 struct dahdi_confinfo ztc; 00106 struct ast_frame *f; 00107 struct ast_channel *c; 00108 struct ast_frame fr; 00109 int outfd; 00110 int ms; 00111 int nfds; 00112 int res; 00113 int flags; 00114 int retryzap; 00115 int origfd; 00116 int ret = -1; 00117 struct dahdi_bufferinfo bi; 00118 char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET]; 00119 char *buf = __buf + AST_FRIENDLY_OFFSET; 00120 00121 /* Set it into U-law mode (write) */ 00122 if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) { 00123 ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name); 00124 goto outrun; 00125 } 00126 00127 /* Set it into U-law mode (read) */ 00128 if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) { 00129 ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name); 00130 goto outrun; 00131 } 00132 ast_indicate(chan, -1); 00133 retryzap = strcasecmp(chan->tech->type, dahdi_chan_name); 00134 zapretry: 00135 origfd = chan->fds[0]; 00136 if (retryzap) { 00137 #ifdef HAVE_ZAPTEL 00138 fd = open("/dev/zap/pseudo", O_RDWR); 00139 #else 00140 fd = open("/dev/dahdi/pseudo", O_RDWR); 00141 #endif 00142 if (fd < 0) { 00143 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 00144 goto outrun; 00145 } 00146 /* Make non-blocking */ 00147 flags = fcntl(fd, F_GETFL); 00148 if (flags < 0) { 00149 ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno)); 00150 close(fd); 00151 goto outrun; 00152 } 00153 if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) { 00154 ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno)); 00155 close(fd); 00156 goto outrun; 00157 } 00158 /* Setup buffering information */ 00159 memset(&bi, 0, sizeof(bi)); 00160 bi.bufsize = CONF_SIZE; 00161 bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; 00162 bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; 00163 bi.numbufs = 4; 00164 if (ioctl(fd, DAHDI_SET_BUFINFO, &bi)) { 00165 ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno)); 00166 close(fd); 00167 goto outrun; 00168 } 00169 nfds = 1; 00170 } else { 00171 /* XXX Make sure we're not running on a pseudo channel XXX */ 00172 fd = chan->fds[0]; 00173 nfds = 0; 00174 } 00175 memset(&ztc, 0, sizeof(ztc)); 00176 /* Check to see if we're in a conference... */ 00177 ztc.chan = 0; 00178 if (ioctl(fd, DAHDI_GETCONF, &ztc)) { 00179 ast_log(LOG_WARNING, "Error getting conference\n"); 00180 close(fd); 00181 goto outrun; 00182 } 00183 if (ztc.confmode) { 00184 /* Whoa, already in a conference... Retry... */ 00185 if (!retryzap) { 00186 ast_log(LOG_DEBUG, "Channel is in a conference already, retrying with pseudo\n"); 00187 retryzap = 1; 00188 goto zapretry; 00189 } 00190 } 00191 memset(&ztc, 0, sizeof(ztc)); 00192 /* Add us to the conference */ 00193 ztc.chan = 0; 00194 ztc.confno = confno; 00195 ztc.confmode = DAHDI_CONF_MONITORBOTH; 00196 00197 if (ioctl(fd, DAHDI_SETCONF, &ztc)) { 00198 ast_log(LOG_WARNING, "Error setting conference\n"); 00199 close(fd); 00200 goto outrun; 00201 } 00202 ast_log(LOG_DEBUG, "Placed channel %s in channel %d monitor\n", chan->name, confno); 00203 00204 for(;;) { 00205 outfd = -1; 00206 ms = -1; 00207 c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms); 00208 if (c) { 00209 if (c->fds[0] != origfd) { 00210 if (retryzap) { 00211 /* Kill old pseudo */ 00212 close(fd); 00213 } 00214 ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n"); 00215 retryzap = 0; 00216 goto zapretry; 00217 } 00218 f = ast_read(c); 00219 if (!f) 00220 break; 00221 if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) { 00222 ret = 0; 00223 ast_frfree(f); 00224 break; 00225 } else if (fd != chan->fds[0]) { 00226 if (f->frametype == AST_FRAME_VOICE) { 00227 if (f->subclass == AST_FORMAT_ULAW) { 00228 /* Carefully write */ 00229 careful_write(fd, f->data, f->datalen); 00230 } else 00231 ast_log(LOG_WARNING, "Huh? Got a non-ulaw (%d) frame in the conference\n", f->subclass); 00232 } 00233 } 00234 ast_frfree(f); 00235 } else if (outfd > -1) { 00236 res = read(outfd, buf, CONF_SIZE); 00237 if (res > 0) { 00238 memset(&fr, 0, sizeof(fr)); 00239 fr.frametype = AST_FRAME_VOICE; 00240 fr.subclass = AST_FORMAT_ULAW; 00241 fr.datalen = res; 00242 fr.samples = res; 00243 fr.data = buf; 00244 fr.offset = AST_FRIENDLY_OFFSET; 00245 if (ast_write(chan, &fr) < 0) { 00246 ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno)); 00247 /* break; */ 00248 } 00249 } else 00250 ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno)); 00251 } 00252 } 00253 if (fd != chan->fds[0]) 00254 close(fd); 00255 else { 00256 /* Take out of conference */ 00257 /* Add us to the conference */ 00258 ztc.chan = 0; 00259 ztc.confno = 0; 00260 ztc.confmode = 0; 00261 if (ioctl(fd, DAHDI_SETCONF, &ztc)) { 00262 ast_log(LOG_WARNING, "Error setting conference\n"); 00263 } 00264 } 00265 00266 outrun: 00267 00268 return ret; 00269 }
static int exec | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | dahdimode | |||
) | [static] |
Definition at line 271 of file app_dahdibarge.c.
References ast_channel::_state, ast_answer(), ast_app_getdata(), ast_log(), ast_module_user_add, ast_module_user_remove, AST_STATE_UP, ast_strlen_zero(), ast_module_user::chan, conf_run(), and LOG_WARNING.
Referenced by exec_dahdi(), exec_warn(), exec_zap(), and load_module().
00272 { 00273 int res=-1; 00274 struct ast_module_user *u; 00275 int retrycnt = 0; 00276 int confflags = 0; 00277 int confno = 0; 00278 char confstr[80] = ""; 00279 00280 u = ast_module_user_add(chan); 00281 00282 if (!ast_strlen_zero(data)) { 00283 if (dahdimode) { 00284 if ((sscanf(data, "DAHDI/%d", &confno) != 1) && 00285 (sscanf(data, "%d", &confno) != 1)) { 00286 ast_log(LOG_WARNING, "Argument (if specified) must be a channel number, not '%s'\n", (char *) data); 00287 ast_module_user_remove(u); 00288 return 0; 00289 } 00290 } else { 00291 if ((sscanf(data, "Zap/%d", &confno) != 1) && 00292 (sscanf(data, "%d", &confno) != 1)) { 00293 ast_log(LOG_WARNING, "Argument (if specified) must be a channel number, not '%s'\n", (char *) data); 00294 ast_module_user_remove(u); 00295 return 0; 00296 } 00297 } 00298 } 00299 00300 if (chan->_state != AST_STATE_UP) 00301 ast_answer(chan); 00302 00303 while(!confno && (++retrycnt < 4)) { 00304 /* Prompt user for conference number */ 00305 confstr[0] = '\0'; 00306 res = ast_app_getdata(chan, "conf-getchannel",confstr, sizeof(confstr) - 1, 0); 00307 if (res <0) goto out; 00308 if (sscanf(confstr, "%d", &confno) != 1) 00309 confno = 0; 00310 } 00311 if (confno) { 00312 /* XXX Should prompt user for pin if pin is required XXX */ 00313 /* Run the conference */ 00314 res = conf_run(chan, confno, confflags); 00315 } 00316 out: 00317 /* Do the conference */ 00318 ast_module_user_remove(u); 00319 return res; 00320 }
static int exec_dahdi | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 329 of file app_dahdibarge.c.
References ast_module_user::chan, and exec().
Referenced by load_module().
static int exec_zap | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 322 of file app_dahdibarge.c.
References ast_log(), ast_module_user::chan, exec(), and LOG_WARNING.
Referenced by load_module().
00323 { 00324 ast_log(LOG_WARNING, "Use of the command %s is deprecated, please use %s instead.\n", zap_app, dahdi_app); 00325 00326 return exec(chan, data, 0); 00327 }
static int load_module | ( | void | ) | [static] |
Definition at line 349 of file app_dahdibarge.c.
References ast_register_application(), CHAN_DAHDI_PLUS_ZAP_MODE, dahdi_chan_mode, exec_dahdi(), and exec_zap().
00350 { 00351 int res = 0; 00352 00353 if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { 00354 res |= ast_register_application(dahdi_app, exec_dahdi, dahdi_synopsis, dahdi_descrip); 00355 } 00356 00357 res |= ast_register_application(zap_app, exec_zap, zap_synopsis, zap_descrip); 00358 00359 return res; 00360 }
static int unload_module | ( | void | ) | [static] |
Definition at line 334 of file app_dahdibarge.c.
References ast_module_user_hangup_all, ast_unregister_application(), CHAN_DAHDI_PLUS_ZAP_MODE, and dahdi_chan_mode.
00335 { 00336 int res = 0; 00337 00338 if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { 00339 res |= ast_unregister_application(dahdi_app); 00340 } 00341 00342 res |= ast_unregister_application(zap_app); 00343 00344 ast_module_user_hangup_all(); 00345 00346 return res; 00347 }
char* dahdi_app = "DAHDIBarge" [static] |
Definition at line 64 of file app_dahdibarge.c.
Referenced by exec_warn(), load_module(), and unload_module().
char* dahdi_descrip [static] |
Initial value:
" DAHDIBarge([channel]): Barges in on a specified DAHDI\n" "channel or prompts if one is not specified. Returns\n" "-1 when caller user hangs up and is independent of the\n" "state of the channel being monitored."
Definition at line 70 of file app_dahdibarge.c.
Referenced by load_module().
char* dahdi_synopsis = "Barge in (monitor) DAHDI channel" [static] |
char* zap_app = "ZapBarge" [static] |
Definition at line 65 of file app_dahdibarge.c.
Referenced by exec_warn(), load_module(), and unload_module().
char* zap_descrip [static] |
Initial value:
" ZapBarge([channel]): Barges in on a specified Zaptel\n" "channel or prompts if one is not specified. Returns\n" "-1 when caller user hangs up and is independent of the\n" "state of the channel being monitored."
Definition at line 76 of file app_dahdibarge.c.
Referenced by load_module().
char* zap_synopsis = "Barge in (monitor) Zap channel" [static] |