Thu Jul 9 13:40:44 2009

Asterisk developer's documentation


app_dahdibarge.c File Reference

DAHDI Barge support. More...

#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_infoast_module_info = &__mod_info
static char * descrip
static char * synopsis = "Barge in (monitor) DAHDI channel"


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 67 of file app_dahdibarge.c.

Referenced by conf_run().


Function Documentation

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

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 }


Variable Documentation

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.

char* synopsis = "Barge in (monitor) DAHDI channel" [static]

Definition at line 58 of file app_dahdibarge.c.


Generated on Thu Jul 9 13:40:44 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7