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