#include "asterisk.h"
#include <sys/ioctl.h>
#include <dahdi/user.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/app.h"
#include "asterisk/cli.h"
#include "asterisk/say.h"
#include "asterisk/utils.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_exec (struct ast_channel *chan, void *data) |
static int | conf_run (struct ast_channel *chan, int confno, int confflags) |
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 , .description = "Barge in on DAHDI 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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } |
static char * | app = "DAHDIBarge" |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static char * | descrip |
static char * | synopsis = "Barge in (monitor) DAHDI channel" |
Definition in file app_dahdibarge.c.
#define CONF_SIZE 160 |
static void __reg_module | ( | void | ) | [static] |
Definition at line 300 of file app_dahdibarge.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 300 of file app_dahdibarge.c.
static int careful_write | ( | int | fd, | |
unsigned char * | data, | |||
int | len | |||
) | [static] |
Definition at line 69 of file app_dahdibarge.c.
References ast_log(), errno, and LOG_WARNING.
Referenced by conf_play(), and conf_run().
00070 { 00071 int res; 00072 while(len) { 00073 res = write(fd, data, len); 00074 if (res < 1) { 00075 if (errno != EAGAIN) { 00076 ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno)); 00077 return -1; 00078 } else 00079 return 0; 00080 } 00081 len -= res; 00082 data += res; 00083 } 00084 return 0; 00085 }
static int conf_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 253 of file app_dahdibarge.c.
References ast_channel::_state, ast_answer(), ast_app_getdata(), ast_log(), AST_STATE_UP, ast_strlen_zero(), chan, conf_run(), and LOG_WARNING.
Referenced by load_module().
00254 { 00255 int res=-1; 00256 int retrycnt = 0; 00257 int confflags = 0; 00258 int confno = 0; 00259 char confstr[80] = ""; 00260 00261 if (!ast_strlen_zero(data)) { 00262 if ((sscanf(data, "DAHDI/%d", &confno) != 1) && 00263 (sscanf(data, "%d", &confno) != 1)) { 00264 ast_log(LOG_WARNING, "DAHDIBarge Argument (if specified) must be a channel number, not '%s'\n", (char *)data); 00265 return 0; 00266 } 00267 } 00268 00269 if (chan->_state != AST_STATE_UP) 00270 ast_answer(chan); 00271 00272 while(!confno && (++retrycnt < 4)) { 00273 /* Prompt user for conference number */ 00274 confstr[0] = '\0'; 00275 res = ast_app_getdata(chan, "conf-getchannel",confstr, sizeof(confstr) - 1, 0); 00276 if (res <0) goto out; 00277 if (sscanf(confstr, "%d", &confno) != 1) 00278 confno = 0; 00279 } 00280 if (confno) { 00281 /* XXX Should prompt user for pin if pin is required XXX */ 00282 /* Run the conference */ 00283 res = conf_run(chan, confno, confflags); 00284 } 00285 out: 00286 /* Do the conference */ 00287 return res; 00288 }
static int conf_run | ( | struct ast_channel * | chan, | |
int | confno, | |||
int | confflags | |||
) | [static] |
Definition at line 87 of file app_dahdibarge.c.
References ast_debug, 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(), buf, careful_write(), chan, CONF_SIZE, errno, f, ast_channel::fds, ast_frame::flags, LOG_WARNING, ast_channel::name, ast_channel::tech, and ast_channel_tech::type.
Referenced by conf_exec(), run_station(), sla_station_exec(), and sla_trunk_exec().
00088 { 00089 int fd; 00090 struct dahdi_confinfo dahdic; 00091 struct ast_frame *f; 00092 struct ast_channel *c; 00093 struct ast_frame fr; 00094 int outfd; 00095 int ms; 00096 int nfds; 00097 int res; 00098 int flags; 00099 int retrydahdi; 00100 int origfd; 00101 int ret = -1; 00102 00103 struct dahdi_bufferinfo bi; 00104 char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET]; 00105 char *buf = __buf + AST_FRIENDLY_OFFSET; 00106 00107 /* Set it into U-law mode (write) */ 00108 if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) { 00109 ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name); 00110 goto outrun; 00111 } 00112 00113 /* Set it into U-law mode (read) */ 00114 if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) { 00115 ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name); 00116 goto outrun; 00117 } 00118 ast_indicate(chan, -1); 00119 retrydahdi = strcasecmp(chan->tech->type, "DAHDI"); 00120 dahdiretry: 00121 origfd = chan->fds[0]; 00122 if (retrydahdi) { 00123 fd = open("/dev/dahdi/pseudo", O_RDWR); 00124 if (fd < 0) { 00125 ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno)); 00126 goto outrun; 00127 } 00128 /* Make non-blocking */ 00129 flags = fcntl(fd, F_GETFL); 00130 if (flags < 0) { 00131 ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno)); 00132 close(fd); 00133 goto outrun; 00134 } 00135 if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) { 00136 ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno)); 00137 close(fd); 00138 goto outrun; 00139 } 00140 /* Setup buffering information */ 00141 memset(&bi, 0, sizeof(bi)); 00142 bi.bufsize = CONF_SIZE; 00143 bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; 00144 bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; 00145 bi.numbufs = 4; 00146 if (ioctl(fd, DAHDI_SET_BUFINFO, &bi)) { 00147 ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno)); 00148 close(fd); 00149 goto outrun; 00150 } 00151 nfds = 1; 00152 } else { 00153 /* XXX Make sure we're not running on a pseudo channel XXX */ 00154 fd = chan->fds[0]; 00155 nfds = 0; 00156 } 00157 memset(&dahdic, 0, sizeof(dahdic)); 00158 /* Check to see if we're in a conference... */ 00159 dahdic.chan = 0; 00160 if (ioctl(fd, DAHDI_GETCONF, &dahdic)) { 00161 ast_log(LOG_WARNING, "Error getting conference\n"); 00162 close(fd); 00163 goto outrun; 00164 } 00165 if (dahdic.confmode) { 00166 /* Whoa, already in a conference... Retry... */ 00167 if (!retrydahdi) { 00168 ast_debug(1, "DAHDI channel is in a conference already, retrying with pseudo\n"); 00169 retrydahdi = 1; 00170 goto dahdiretry; 00171 } 00172 } 00173 memset(&dahdic, 0, sizeof(dahdic)); 00174 /* Add us to the conference */ 00175 dahdic.chan = 0; 00176 dahdic.confno = confno; 00177 dahdic.confmode = DAHDI_CONF_MONITORBOTH; 00178 00179 if (ioctl(fd, DAHDI_SETCONF, &dahdic)) { 00180 ast_log(LOG_WARNING, "Error setting conference\n"); 00181 close(fd); 00182 goto outrun; 00183 } 00184 ast_debug(1, "Placed channel %s in DAHDI channel %d monitor\n", chan->name, confno); 00185 00186 for(;;) { 00187 outfd = -1; 00188 ms = -1; 00189 c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms); 00190 if (c) { 00191 if (c->fds[0] != origfd) { 00192 if (retrydahdi) { 00193 /* Kill old pseudo */ 00194 close(fd); 00195 } 00196 ast_debug(1, "Ooh, something swapped out under us, starting over\n"); 00197 retrydahdi = 0; 00198 goto dahdiretry; 00199 } 00200 f = ast_read(c); 00201 if (!f) 00202 break; 00203 if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) { 00204 ret = 0; 00205 ast_frfree(f); 00206 break; 00207 } else if (fd != chan->fds[0]) { 00208 if (f->frametype == AST_FRAME_VOICE) { 00209 if (f->subclass == AST_FORMAT_ULAW) { 00210 /* Carefully write */ 00211 careful_write(fd, f->data, f->datalen); 00212 } else 00213 ast_log(LOG_WARNING, "Huh? Got a non-ulaw (%d) frame in the conference\n", f->subclass); 00214 } 00215 } 00216 ast_frfree(f); 00217 } else if (outfd > -1) { 00218 res = read(outfd, buf, CONF_SIZE); 00219 if (res > 0) { 00220 memset(&fr, 0, sizeof(fr)); 00221 fr.frametype = AST_FRAME_VOICE; 00222 fr.subclass = AST_FORMAT_ULAW; 00223 fr.datalen = res; 00224 fr.samples = res; 00225 fr.data = buf; 00226 fr.offset = AST_FRIENDLY_OFFSET; 00227 if (ast_write(chan, &fr) < 0) { 00228 ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno)); 00229 /* break; */ 00230 } 00231 } else 00232 ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno)); 00233 } 00234 } 00235 if (fd != chan->fds[0]) 00236 close(fd); 00237 else { 00238 /* Take out of conference */ 00239 /* Add us to the conference */ 00240 dahdic.chan = 0; 00241 dahdic.confno = 0; 00242 dahdic.confmode = 0; 00243 if (ioctl(fd, DAHDI_SETCONF, &dahdic)) { 00244 ast_log(LOG_WARNING, "Error setting conference\n"); 00245 } 00246 } 00247 00248 outrun: 00249 00250 return ret; 00251 }
static int load_module | ( | void | ) | [static] |
Definition at line 295 of file app_dahdibarge.c.
References AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application, and conf_exec().
00296 { 00297 return ((ast_register_application(app, conf_exec, synopsis, descrip)) ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS); 00298 }
static int unload_module | ( | void | ) | [static] |
Definition at line 290 of file app_dahdibarge.c.
References ast_unregister_application().
00291 { 00292 return ast_unregister_application(app); 00293 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Barge in on DAHDI 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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 300 of file app_dahdibarge.c.
char* app = "DAHDIBarge" [static] |
Definition at line 56 of file app_dahdibarge.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 300 of file app_dahdibarge.c.
char* 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 60 of file app_dahdibarge.c.
Definition at line 58 of file app_dahdibarge.c.