#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 | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
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 struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Barge in on channel 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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } |
static const struct ast_module_info * | ast_module_info = &__mod_info |
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 |
static void __reg_module | ( | void | ) | [static] |
Definition at line 358 of file app_dahdibarge.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 358 of file app_dahdibarge.c.
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, DAHDI_FILE_PSEUDO, errno, f, ast_channel::fds, ast_frame::flags, LOG_DEBUG, LOG_WARNING, ast_channel::name, 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 fd = open(DAHDI_FILE_PSEUDO, O_RDWR); 00138 if (fd < 0) { 00139 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 00140 goto outrun; 00141 } 00142 /* Make non-blocking */ 00143 flags = fcntl(fd, F_GETFL); 00144 if (flags < 0) { 00145 ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno)); 00146 close(fd); 00147 goto outrun; 00148 } 00149 if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) { 00150 ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno)); 00151 close(fd); 00152 goto outrun; 00153 } 00154 /* Setup buffering information */ 00155 memset(&bi, 0, sizeof(bi)); 00156 bi.bufsize = CONF_SIZE; 00157 bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; 00158 bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; 00159 bi.numbufs = 4; 00160 if (ioctl(fd, DAHDI_SET_BUFINFO, &bi)) { 00161 ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno)); 00162 close(fd); 00163 goto outrun; 00164 } 00165 nfds = 1; 00166 } else { 00167 /* XXX Make sure we're not running on a pseudo channel XXX */ 00168 fd = chan->fds[0]; 00169 nfds = 0; 00170 } 00171 memset(&ztc, 0, sizeof(ztc)); 00172 /* Check to see if we're in a conference... */ 00173 ztc.chan = 0; 00174 if (ioctl(fd, DAHDI_GETCONF, &ztc)) { 00175 ast_log(LOG_WARNING, "Error getting conference\n"); 00176 close(fd); 00177 goto outrun; 00178 } 00179 if (ztc.confmode) { 00180 /* Whoa, already in a conference... Retry... */ 00181 if (!retryzap) { 00182 ast_log(LOG_DEBUG, "Channel is in a conference already, retrying with pseudo\n"); 00183 retryzap = 1; 00184 goto zapretry; 00185 } 00186 } 00187 memset(&ztc, 0, sizeof(ztc)); 00188 /* Add us to the conference */ 00189 ztc.chan = 0; 00190 ztc.confno = confno; 00191 ztc.confmode = DAHDI_CONF_MONITORBOTH; 00192 00193 if (ioctl(fd, DAHDI_SETCONF, &ztc)) { 00194 ast_log(LOG_WARNING, "Error setting conference\n"); 00195 close(fd); 00196 goto outrun; 00197 } 00198 ast_log(LOG_DEBUG, "Placed channel %s in channel %d monitor\n", chan->name, confno); 00199 00200 for(;;) { 00201 outfd = -1; 00202 ms = -1; 00203 c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms); 00204 if (c) { 00205 if (c->fds[0] != origfd) { 00206 if (retryzap) { 00207 /* Kill old pseudo */ 00208 close(fd); 00209 } 00210 ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n"); 00211 retryzap = 0; 00212 goto zapretry; 00213 } 00214 f = ast_read(c); 00215 if (!f) 00216 break; 00217 if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) { 00218 ret = 0; 00219 ast_frfree(f); 00220 break; 00221 } else if (fd != chan->fds[0]) { 00222 if (f->frametype == AST_FRAME_VOICE) { 00223 if (f->subclass == AST_FORMAT_ULAW) { 00224 /* Carefully write */ 00225 careful_write(fd, f->data, f->datalen); 00226 } else 00227 ast_log(LOG_WARNING, "Huh? Got a non-ulaw (%d) frame in the conference\n", f->subclass); 00228 } 00229 } 00230 ast_frfree(f); 00231 } else if (outfd > -1) { 00232 res = read(outfd, buf, CONF_SIZE); 00233 if (res > 0) { 00234 memset(&fr, 0, sizeof(fr)); 00235 fr.frametype = AST_FRAME_VOICE; 00236 fr.subclass = AST_FORMAT_ULAW; 00237 fr.datalen = res; 00238 fr.samples = res; 00239 fr.data = buf; 00240 fr.offset = AST_FRIENDLY_OFFSET; 00241 if (ast_write(chan, &fr) < 0) { 00242 ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno)); 00243 /* break; */ 00244 } 00245 } else 00246 ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno)); 00247 } 00248 } 00249 if (fd != chan->fds[0]) 00250 close(fd); 00251 else { 00252 /* Take out of conference */ 00253 /* Add us to the conference */ 00254 ztc.chan = 0; 00255 ztc.confno = 0; 00256 ztc.confmode = 0; 00257 if (ioctl(fd, DAHDI_SETCONF, &ztc)) { 00258 ast_log(LOG_WARNING, "Error setting conference\n"); 00259 } 00260 } 00261 00262 outrun: 00263 00264 return ret; 00265 }
static int exec | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | dahdimode | |||
) | [static] |
Definition at line 267 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().
00268 { 00269 int res=-1; 00270 struct ast_module_user *u; 00271 int retrycnt = 0; 00272 int confflags = 0; 00273 int confno = 0; 00274 char confstr[80] = ""; 00275 00276 u = ast_module_user_add(chan); 00277 00278 if (!ast_strlen_zero(data)) { 00279 if (dahdimode) { 00280 if ((sscanf(data, "DAHDI/%30d", &confno) != 1) && 00281 (sscanf(data, "%30d", &confno) != 1)) { 00282 ast_log(LOG_WARNING, "Argument (if specified) must be a channel number, not '%s'\n", (char *) data); 00283 ast_module_user_remove(u); 00284 return 0; 00285 } 00286 } else { 00287 if ((sscanf(data, "Zap/%30d", &confno) != 1) && 00288 (sscanf(data, "%30d", &confno) != 1)) { 00289 ast_log(LOG_WARNING, "Argument (if specified) must be a channel number, not '%s'\n", (char *) data); 00290 ast_module_user_remove(u); 00291 return 0; 00292 } 00293 } 00294 } 00295 00296 if (chan->_state != AST_STATE_UP) 00297 ast_answer(chan); 00298 00299 while(!confno && (++retrycnt < 4)) { 00300 /* Prompt user for conference number */ 00301 confstr[0] = '\0'; 00302 res = ast_app_getdata(chan, "conf-getchannel",confstr, sizeof(confstr) - 1, 0); 00303 if (res <0) goto out; 00304 if (sscanf(confstr, "%30d", &confno) != 1) 00305 confno = 0; 00306 } 00307 if (confno) { 00308 /* XXX Should prompt user for pin if pin is required XXX */ 00309 /* Run the conference */ 00310 res = conf_run(chan, confno, confflags); 00311 } 00312 out: 00313 /* Do the conference */ 00314 ast_module_user_remove(u); 00315 return res; 00316 }
static int exec_dahdi | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 325 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 318 of file app_dahdibarge.c.
References ast_log(), ast_module_user::chan, exec(), and LOG_WARNING.
Referenced by load_module().
00319 { 00320 ast_log(LOG_WARNING, "Use of the command %s is deprecated, please use %s instead.\n", zap_app, dahdi_app); 00321 00322 return exec(chan, data, 0); 00323 }
static int load_module | ( | void | ) | [static] |
Definition at line 345 of file app_dahdibarge.c.
References ast_register_application(), CHAN_DAHDI_PLUS_ZAP_MODE, dahdi_chan_mode, exec_dahdi(), and exec_zap().
00346 { 00347 int res = 0; 00348 00349 if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { 00350 res |= ast_register_application(dahdi_app, exec_dahdi, dahdi_synopsis, dahdi_descrip); 00351 } 00352 00353 res |= ast_register_application(zap_app, exec_zap, zap_synopsis, zap_descrip); 00354 00355 return res; 00356 }
static int unload_module | ( | void | ) | [static] |
Definition at line 330 of file app_dahdibarge.c.
References ast_module_user_hangup_all, ast_unregister_application(), CHAN_DAHDI_PLUS_ZAP_MODE, and dahdi_chan_mode.
00331 { 00332 int res = 0; 00333 00334 if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) { 00335 res |= ast_unregister_application(dahdi_app); 00336 } 00337 00338 res |= ast_unregister_application(zap_app); 00339 00340 ast_module_user_hangup_all(); 00341 00342 return res; 00343 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Barge in on channel 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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 358 of file app_dahdibarge.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 358 of file app_dahdibarge.c.
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] |