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