Sat Mar 10 01:54:31 2012

Asterisk developer's documentation


app_dahdibarge.c File Reference

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

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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static const char app [] = "DAHDIBarge"
static struct ast_module_infoast_module_info = &__mod_info


Detailed Description

DAHDI Barge support.

Author:
Mark Spencer <markster@digium.com>
Note:
Special thanks to comphealth.com for sponsoring this GPL application.

Definition in file app_dahdibarge.c.


Define Documentation

#define CONF_SIZE   160

Definition at line 77 of file app_dahdibarge.c.

Referenced by conf_run().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 310 of file app_dahdibarge.c.

static void __unreg_module ( void   )  [static]

Definition at line 310 of file app_dahdibarge.c.

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_play(), and 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(), 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().

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().

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 }


Variable Documentation

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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 310 of file app_dahdibarge.c.

const char app[] = "DAHDIBarge" [static]

Definition at line 75 of file app_dahdibarge.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 310 of file app_dahdibarge.c.


Generated on Sat Mar 10 01:54:31 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7