Sat Aug 6 00:39:34 2011

Asterisk developer's documentation


app_dahdibarge.c File Reference

Zap Barge support. More...

#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/app.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/say.h"
#include "asterisk/utils.h"
#include "asterisk/dahdi_compat.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_run (struct ast_channel *chan, int confno, int confflags)
static int exec (struct ast_channel *chan, void *data, int dahdimode)
static int exec_dahdi (struct ast_channel *chan, void *data)
static int exec_zap (struct ast_channel *chan, void *data)
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 | AST_MODFLAG_BUILDSUM, .description = "Barge in on 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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, }
static const struct ast_module_infoast_module_info = &__mod_info
static char * dahdi_app = "DAHDIBarge"
static char * dahdi_descrip
static char * dahdi_synopsis = "Barge in (monitor) DAHDI channel"
static char * zap_app = "ZapBarge"
static char * zap_descrip
static char * zap_synopsis = "Barge in (monitor) Zap channel"


Detailed Description

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

Referenced by conf_run().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 358 of file app_dahdibarge.c.

static void __unreg_module ( void   )  [static]

Definition at line 358 of file app_dahdibarge.c.

static int careful_write ( int  fd,
unsigned char *  data,
int  len 
) [static]

Definition at line 84 of file app_dahdibarge.c.

References ast_log(), errno, and LOG_WARNING.

Referenced by conf_play(), and conf_run().

00085 {
00086    int res;
00087    while(len) {
00088       res = write(fd, data, len);
00089       if (res < 1) {
00090          if (errno != EAGAIN) {
00091             ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno));
00092             return -1;
00093          } else
00094             return 0;
00095       }
00096       len -= res;
00097       data += res;
00098    }
00099    return 0;
00100 }

static int conf_run ( struct ast_channel chan,
int  confno,
int  confflags 
) [static]

Definition at line 102 of file app_dahdibarge.c.

References 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(), careful_write(), CONF_SIZE, dahdi_chan_name, DAHDI_FILE_PSEUDO, errno, f, ast_channel::fds, ast_frame::flags, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::tech, and ast_channel_tech::type.

Referenced by conf_exec(), exec(), run_station(), sla_station_exec(), and sla_trunk_exec().

00103 {
00104    int fd;
00105    struct dahdi_confinfo ztc;
00106    struct ast_frame *f;
00107    struct ast_channel *c;
00108    struct ast_frame fr;
00109    int outfd;
00110    int ms;
00111    int nfds;
00112    int res;
00113    int flags;
00114    int retryzap;
00115    int origfd;
00116    int ret = -1;
00117    struct dahdi_bufferinfo bi;
00118    char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
00119    char *buf = __buf + AST_FRIENDLY_OFFSET;
00120 
00121    /* Set it into U-law mode (write) */
00122    if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) {
00123       ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name);
00124       goto outrun;
00125    }
00126 
00127    /* Set it into U-law mode (read) */
00128    if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) {
00129       ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name);
00130       goto outrun;
00131    }
00132    ast_indicate(chan, -1);
00133    retryzap = strcasecmp(chan->tech->type, dahdi_chan_name);
00134 zapretry:
00135    origfd = chan->fds[0];
00136    if (retryzap) {
00137       fd = open(DAHDI_FILE_PSEUDO, O_RDWR);
00138       if (fd < 0) {
00139          ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
00140          goto outrun;
00141       }
00142       /* Make non-blocking */
00143       flags = fcntl(fd, F_GETFL);
00144       if (flags < 0) {
00145          ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno));
00146          close(fd);
00147          goto outrun;
00148       }
00149       if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
00150          ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno));
00151          close(fd);
00152          goto outrun;
00153       }
00154       /* Setup buffering information */
00155       memset(&bi, 0, sizeof(bi));
00156       bi.bufsize = CONF_SIZE;
00157       bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
00158       bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
00159       bi.numbufs = 4;
00160       if (ioctl(fd, DAHDI_SET_BUFINFO, &bi)) {
00161          ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno));
00162          close(fd);
00163          goto outrun;
00164       }
00165       nfds = 1;
00166    } else {
00167       /* XXX Make sure we're not running on a pseudo channel XXX */
00168       fd = chan->fds[0];
00169       nfds = 0;
00170    }
00171    memset(&ztc, 0, sizeof(ztc));
00172    /* Check to see if we're in a conference... */
00173    ztc.chan = 0;  
00174    if (ioctl(fd, DAHDI_GETCONF, &ztc)) {
00175       ast_log(LOG_WARNING, "Error getting conference\n");
00176       close(fd);
00177       goto outrun;
00178    }
00179    if (ztc.confmode) {
00180       /* Whoa, already in a conference...  Retry... */
00181       if (!retryzap) {
00182          ast_log(LOG_DEBUG, "Channel is in a conference already, retrying with pseudo\n");
00183          retryzap = 1;
00184          goto zapretry;
00185       }
00186    }
00187    memset(&ztc, 0, sizeof(ztc));
00188    /* Add us to the conference */
00189    ztc.chan = 0;  
00190    ztc.confno = confno;
00191    ztc.confmode = DAHDI_CONF_MONITORBOTH;
00192 
00193    if (ioctl(fd, DAHDI_SETCONF, &ztc)) {
00194       ast_log(LOG_WARNING, "Error setting conference\n");
00195       close(fd);
00196       goto outrun;
00197    }
00198    ast_log(LOG_DEBUG, "Placed channel %s in channel %d monitor\n", chan->name, confno);
00199 
00200    for(;;) {
00201       outfd = -1;
00202       ms = -1;
00203       c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
00204       if (c) {
00205          if (c->fds[0] != origfd) {
00206             if (retryzap) {
00207                /* Kill old pseudo */
00208                close(fd);
00209             }
00210             ast_log(LOG_DEBUG, "Ooh, something swapped out under us, starting over\n");
00211             retryzap = 0;
00212             goto zapretry;
00213          }
00214          f = ast_read(c);
00215          if (!f) 
00216             break;
00217          if ((f->frametype == AST_FRAME_DTMF) && (f->subclass == '#')) {
00218             ret = 0;
00219             ast_frfree(f);
00220             break;
00221          } else if (fd != chan->fds[0]) {
00222             if (f->frametype == AST_FRAME_VOICE) {
00223                if (f->subclass == AST_FORMAT_ULAW) {
00224                   /* Carefully write */
00225                   careful_write(fd, f->data, f->datalen);
00226                } else
00227                   ast_log(LOG_WARNING, "Huh?  Got a non-ulaw (%d) frame in the conference\n", f->subclass);
00228             }
00229          }
00230          ast_frfree(f);
00231       } else if (outfd > -1) {
00232          res = read(outfd, buf, CONF_SIZE);
00233          if (res > 0) {
00234             memset(&fr, 0, sizeof(fr));
00235             fr.frametype = AST_FRAME_VOICE;
00236             fr.subclass = AST_FORMAT_ULAW;
00237             fr.datalen = res;
00238             fr.samples = res;
00239             fr.data = buf;
00240             fr.offset = AST_FRIENDLY_OFFSET;
00241             if (ast_write(chan, &fr) < 0) {
00242                ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno));
00243                /* break; */
00244             }
00245          } else 
00246             ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno));
00247       }
00248    }
00249    if (fd != chan->fds[0])
00250       close(fd);
00251    else {
00252       /* Take out of conference */
00253       /* Add us to the conference */
00254       ztc.chan = 0;  
00255       ztc.confno = 0;
00256       ztc.confmode = 0;
00257       if (ioctl(fd, DAHDI_SETCONF, &ztc)) {
00258          ast_log(LOG_WARNING, "Error setting conference\n");
00259       }
00260    }
00261 
00262 outrun:
00263 
00264    return ret;
00265 }

static int exec ( struct ast_channel chan,
void *  data,
int  dahdimode 
) [static]

Definition at line 267 of file app_dahdibarge.c.

References ast_channel::_state, ast_answer(), ast_app_getdata(), ast_log(), ast_module_user_add, ast_module_user_remove, AST_STATE_UP, ast_strlen_zero(), ast_module_user::chan, conf_run(), and LOG_WARNING.

Referenced by exec_dahdi(), exec_warn(), exec_zap(), and load_module().

00268 {
00269    int res=-1;
00270    struct ast_module_user *u;
00271    int retrycnt = 0;
00272    int confflags = 0;
00273    int confno = 0;
00274    char confstr[80] = "";
00275 
00276    u = ast_module_user_add(chan);
00277    
00278    if (!ast_strlen_zero(data)) {
00279       if (dahdimode) {
00280          if ((sscanf(data, "DAHDI/%30d", &confno) != 1) &&
00281              (sscanf(data, "%30d", &confno) != 1)) {
00282             ast_log(LOG_WARNING, "Argument (if specified) must be a channel number, not '%s'\n", (char *) data);
00283             ast_module_user_remove(u);
00284             return 0;
00285          }
00286       } else {
00287          if ((sscanf(data, "Zap/%30d", &confno) != 1) &&
00288              (sscanf(data, "%30d", &confno) != 1)) {
00289             ast_log(LOG_WARNING, "Argument (if specified) must be a channel number, not '%s'\n", (char *) data);
00290             ast_module_user_remove(u);
00291             return 0;
00292          }
00293       }
00294    }
00295    
00296    if (chan->_state != AST_STATE_UP)
00297       ast_answer(chan);
00298 
00299    while(!confno && (++retrycnt < 4)) {
00300       /* Prompt user for conference number */
00301       confstr[0] = '\0';
00302       res = ast_app_getdata(chan, "conf-getchannel",confstr, sizeof(confstr) - 1, 0);
00303       if (res <0) goto out;
00304       if (sscanf(confstr, "%30d", &confno) != 1)
00305          confno = 0;
00306    }
00307    if (confno) {
00308       /* XXX Should prompt user for pin if pin is required XXX */
00309       /* Run the conference */
00310       res = conf_run(chan, confno, confflags);
00311    }
00312 out:
00313    /* Do the conference */
00314    ast_module_user_remove(u);
00315    return res;
00316 }

static int exec_dahdi ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 325 of file app_dahdibarge.c.

References ast_module_user::chan, and exec().

Referenced by load_module().

00326 {
00327    return exec(chan, data, 1);
00328 }

static int exec_zap ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 318 of file app_dahdibarge.c.

References ast_log(), ast_module_user::chan, exec(), and LOG_WARNING.

Referenced by load_module().

00319 {
00320    ast_log(LOG_WARNING, "Use of the command %s is deprecated, please use %s instead.\n", zap_app, dahdi_app);
00321    
00322    return exec(chan, data, 0);
00323 }

static int load_module ( void   )  [static]

Definition at line 345 of file app_dahdibarge.c.

References ast_register_application(), CHAN_DAHDI_PLUS_ZAP_MODE, dahdi_chan_mode, exec_dahdi(), and exec_zap().

00346 {
00347    int res = 0;
00348 
00349    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
00350       res |= ast_register_application(dahdi_app, exec_dahdi, dahdi_synopsis, dahdi_descrip);
00351    }
00352 
00353    res |= ast_register_application(zap_app, exec_zap, zap_synopsis, zap_descrip);
00354 
00355    return res;
00356 }

static int unload_module ( void   )  [static]

Definition at line 330 of file app_dahdibarge.c.

References ast_module_user_hangup_all, ast_unregister_application(), CHAN_DAHDI_PLUS_ZAP_MODE, and dahdi_chan_mode.

00331 {
00332    int res = 0;
00333 
00334    if (*dahdi_chan_mode == CHAN_DAHDI_PLUS_ZAP_MODE) {
00335       res |= ast_unregister_application(dahdi_app);
00336    }
00337 
00338    res |= ast_unregister_application(zap_app);
00339    
00340    ast_module_user_hangup_all();
00341 
00342    return res;
00343 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Barge in on 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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 358 of file app_dahdibarge.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 358 of file app_dahdibarge.c.

char* dahdi_app = "DAHDIBarge" [static]

Definition at line 64 of file app_dahdibarge.c.

Referenced by exec_warn(), load_module(), and unload_module().

char* dahdi_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 70 of file app_dahdibarge.c.

Referenced by load_module().

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

Definition at line 67 of file app_dahdibarge.c.

Referenced by load_module().

char* zap_app = "ZapBarge" [static]

Definition at line 65 of file app_dahdibarge.c.

Referenced by exec_warn(), load_module(), and unload_module().

char* zap_descrip [static]

Initial value:

 
"  ZapBarge([channel]): Barges in on a specified Zaptel\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 76 of file app_dahdibarge.c.

Referenced by load_module().

char* zap_synopsis = "Barge in (monitor) Zap channel" [static]

Definition at line 68 of file app_dahdibarge.c.

Referenced by load_module().


Generated on Sat Aug 6 00:39:34 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7