Mon Jun 27 16:50:58 2011

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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 75 of file app_dahdibarge.c.

Referenced by conf_run().


Function Documentation

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

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 }


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 = "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.


Generated on Mon Jun 27 16:50:58 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7