Fri May 26 01:46:59 2006

Asterisk developer's documentation


chan_oss_old.c File Reference

#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <soundcard.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/options.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/endian.h"
#include "busy.h"
#include "ringtone.h"
#include "ring10.h"
#include "answer.h"

Include dependency graph for chan_oss_old.c:

Go to the source code of this file.

Data Structures

struct  chan_oss_pvt
struct  sound

Defines

#define BUFFER_FMT   ((buffersize * 10) << 16) | (0x0006);
#define DEV_DSP   "/dev/dsp"
#define FRAME_SIZE   160
#define MAX_BUFFER_SIZE   100
#define MIN(a, b)   ((a) < (b) ? (a) : (b))
#define MIN_SWITCH_TIME   600

Functions

static void answer_sound (void)
 AST_MUTEX_DEFINE_STATIC (usecnt_lock)
static char * autoanswer_complete (char *line, char *word, int pos, int state)
static int console_answer (int fd, int argc, char *argv[])
static int console_autoanswer (int fd, int argc, char *argv[])
static int console_dial (int fd, int argc, char *argv[])
static int console_flash (int fd, int argc, char *argv[])
static int console_hangup (int fd, int argc, char *argv[])
static int console_sendtext (int fd, int argc, char *argv[])
static int console_transfer (int fd, int argc, char *argv[])
char * description ()
 Provides a description of the module.
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module ()
 Initialize the module.
static int oss_answer (struct ast_channel *c)
static int oss_call (struct ast_channel *c, char *dest, int timeout)
static int oss_digit (struct ast_channel *c, char digit)
static int oss_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
static int oss_hangup (struct ast_channel *c)
static int oss_indicate (struct ast_channel *chan, int cond)
static struct ast_channeloss_new (struct chan_oss_pvt *p, int state)
static struct ast_frameoss_read (struct ast_channel *chan)
static struct ast_channeloss_request (const char *type, int format, void *data, int *cause)
static int oss_text (struct ast_channel *c, const char *text)
static int oss_write (struct ast_channel *chan, struct ast_frame *f)
static int send_sound (void)
static int setformat (void)
static void * sound_thread (void *unused)
static int soundcard_init (void)
static int soundcard_setinput (int force)
static int soundcard_setoutput (int force)
static int soundcard_writeframe (short *data)
static int time_has_passed (void)
int unload_module ()
 Cleanup all module structures, sockets, etc.
int usecount ()
 Provides a usecount.

Variables

static char answer_usage []
static int autoanswer = 1
static char autoanswer_usage []
static int buffersize = 3
static const char config [] = "oss.conf"
static char context [AST_MAX_CONTEXT] = "default"
static int cursound = -1
static const char desc [] = "OSS Console Channel Driver"
static char dial_usage []
static char exten [AST_MAX_EXTENSION] = "s"
static char flash_usage []
static int full_duplex = 0
static char hangup_usage []
static int hookstate = 0
static char language [MAX_LANGUAGE] = ""
static struct timeval lasttime
static struct ast_cli_entry myclis []
static int nosound = 0
static int offset = 0
static struct chan_oss_pvt oss
static const struct ast_channel_tech oss_tech
static int playbackonly = 0
static int readmode = 1
static int sampsent = 0
static char sendtext_usage []
static short silence [FRAME_SIZE] = {0, }
static int silencelen = 0
static int silencesuppression = 0
static int silencethreshold = 1000
static int sndcmd [2]
static int sounddev = -1
static struct sound sounds []
static pthread_t sthread
static const char tdesc [] = "OSS Console Channel Driver"
static char transfer_usage []
static const char type [] = "Console"
static int usecnt


Define Documentation

#define BUFFER_FMT   ((buffersize * 10) << 16) | (0x0006);
 

Definition at line 81 of file chan_oss_old.c.

#define DEV_DSP   "/dev/dsp"
 

Definition at line 72 of file chan_oss_old.c.

#define FRAME_SIZE   160
 

Definition at line 76 of file chan_oss_old.c.

#define MAX_BUFFER_SIZE   100
 

Definition at line 182 of file chan_oss_old.c.

#define MIN a,
 )     ((a) < (b) ? (a) : (b))
 

#define MIN_SWITCH_TIME   600
 

Definition at line 84 of file chan_oss_old.c.


Function Documentation

static void answer_sound void   )  [static]
 

Definition at line 531 of file chan_oss_old.c.

References nosound, and sndcmd.

00532 {
00533    int res;
00534    nosound = 1;
00535    res = 4;
00536    write(sndcmd[1], &res, sizeof(res));
00537    
00538 }

AST_MUTEX_DEFINE_STATIC usecnt_lock   ) 
 

static char* autoanswer_complete char *  line,
char *  word,
int  pos,
int  state
[static]
 

Definition at line 837 of file chan_oss_old.c.

References ast_strlen_zero(), MIN, and strdup.

00838 {
00839 #ifndef MIN
00840 #define MIN(a,b) ((a) < (b) ? (a) : (b))
00841 #endif
00842    switch(state) {
00843    case 0:
00844       if (!ast_strlen_zero(word) && !strncasecmp(word, "on", MIN(strlen(word), 2)))
00845          return strdup("on");
00846    case 1:
00847       if (!ast_strlen_zero(word) && !strncasecmp(word, "off", MIN(strlen(word), 3)))
00848          return strdup("off");
00849    default:
00850       return NULL;
00851    }
00852    return NULL;
00853 }

static int console_answer int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 861 of file chan_oss_old.c.

References answer_sound(), ast_cli(), AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_queue_frame(), cursound, oss, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00862 {
00863    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
00864    if (argc != 1)
00865       return RESULT_SHOWUSAGE;
00866    if (!oss.owner) {
00867       ast_cli(fd, "No one is calling us\n");
00868       return RESULT_FAILURE;
00869    }
00870    hookstate = 1;
00871    cursound = -1;
00872    ast_queue_frame(oss.owner, &f);
00873    answer_sound();
00874    return RESULT_SUCCESS;
00875 }

static int console_autoanswer int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 819 of file chan_oss_old.c.

References ast_cli(), autoanswer, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00820 {
00821    if ((argc != 1) && (argc != 2))
00822       return RESULT_SHOWUSAGE;
00823    if (argc == 1) {
00824       ast_cli(fd, "Auto answer is %s.\n", autoanswer ? "on" : "off");
00825       return RESULT_SUCCESS;
00826    } else {
00827       if (!strcasecmp(argv[1], "on"))
00828          autoanswer = -1;
00829       else if (!strcasecmp(argv[1], "off"))
00830          autoanswer = 0;
00831       else
00832          return RESULT_SHOWUSAGE;
00833    }
00834    return RESULT_SUCCESS;
00835 }

static int console_dial int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 955 of file chan_oss_old.c.

References ast_cli(), AST_FRAME_DTMF, ast_queue_frame(), oss, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_frame::subclass.

00956 {
00957    char tmp[256], *tmp2;
00958    char *mye, *myc;
00959    int x;
00960    struct ast_frame f = { AST_FRAME_DTMF, 0 };
00961    if ((argc != 1) && (argc != 2))
00962       return RESULT_SHOWUSAGE;
00963    if (oss.owner) {
00964       if (argc == 2) {
00965          for (x=0;x<strlen(argv[1]);x++) {
00966             f.subclass = argv[1][x];
00967             ast_queue_frame(oss.owner, &f);
00968          }
00969       } else {
00970          ast_cli(fd, "You're already in a call.  You can use this only to dial digits until you hangup\n");
00971          return RESULT_FAILURE;
00972       }
00973       return RESULT_SUCCESS;
00974    }
00975    mye = exten;
00976    myc = context;
00977    if (argc == 2) {
00978       char *stringp=NULL;
00979       strncpy(tmp, argv[1], sizeof(tmp)-1);
00980       stringp=tmp;
00981       strsep(&stringp, "@");
00982       tmp2 = strsep(&stringp, "@");
00983       if (!ast_strlen_zero(tmp))
00984          mye = tmp;
00985       if (!ast_strlen_zero(tmp2))
00986          myc = tmp2;
00987    }
00988    if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
00989       strncpy(oss.exten, mye, sizeof(oss.exten)-1);
00990       strncpy(oss.context, myc, sizeof(oss.context)-1);
00991       hookstate = 1;
00992       oss_new(&oss, AST_STATE_RINGING);
00993    } else
00994       ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
00995    return RESULT_SUCCESS;
00996 }

static int console_flash int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 929 of file chan_oss_old.c.

References ast_cli(), AST_CONTROL_FLASH, AST_FRAME_CONTROL, ast_queue_frame(), cursound, oss, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00930 {
00931    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH };
00932    if (argc != 1)
00933       return RESULT_SHOWUSAGE;
00934    cursound = -1;
00935    if (!oss.owner) {
00936       ast_cli(fd, "No call to flash\n");
00937       return RESULT_FAILURE;
00938    }
00939    hookstate = 0;
00940    if (oss.owner) {
00941       ast_queue_frame(oss.owner, &f);
00942    }
00943    return RESULT_SUCCESS;
00944 }

static int console_hangup int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 913 of file chan_oss_old.c.

References ast_cli(), ast_queue_hangup(), cursound, oss, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

00914 {
00915    if (argc != 1)
00916       return RESULT_SHOWUSAGE;
00917    cursound = -1;
00918    if (!oss.owner && !hookstate) {
00919       ast_cli(fd, "No call to hangup up\n");
00920       return RESULT_FAILURE;
00921    }
00922    hookstate = 0;
00923    if (oss.owner) {
00924       ast_queue_hangup(oss.owner);
00925    }
00926    return RESULT_SUCCESS;
00927 }

static int console_sendtext int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 881 of file chan_oss_old.c.

References ast_cli(), AST_FRAME_TEXT, ast_queue_frame(), ast_strlen_zero(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, oss, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ast_frame::subclass.

00882 {
00883    int tmparg = 2;
00884    char text2send[256] = "";
00885    struct ast_frame f = { 0, };
00886    if (argc < 2)
00887       return RESULT_SHOWUSAGE;
00888    if (!oss.owner) {
00889       ast_cli(fd, "No one is calling us\n");
00890       return RESULT_FAILURE;
00891    }
00892    if (!ast_strlen_zero(text2send))
00893       ast_cli(fd, "Warning: message already waiting to be sent, overwriting\n");
00894    text2send[0] = '\0';
00895    while(tmparg < argc) {
00896       strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1);
00897       strncat(text2send, " ", sizeof(text2send) - strlen(text2send) - 1);
00898    }
00899    if (!ast_strlen_zero(text2send)) {
00900       f.frametype = AST_FRAME_TEXT;
00901       f.subclass = 0;
00902       f.data = text2send;
00903       f.datalen = strlen(text2send);
00904       ast_queue_frame(oss.owner, &f);
00905    }
00906    return RESULT_SUCCESS;
00907 }

static int console_transfer int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 1002 of file chan_oss_old.c.

References ast_async_goto(), ast_bridged_channel(), ast_cli(), ast_exists_extension(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::name, oss, chan_oss_pvt::owner, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01003 {
01004    char tmp[256];
01005    char *context;
01006    if (argc != 2)
01007       return RESULT_SHOWUSAGE;
01008    if (oss.owner && ast_bridged_channel(oss.owner)) {
01009       strncpy(tmp, argv[1], sizeof(tmp) - 1);
01010       context = strchr(tmp, '@');
01011       if (context) {
01012          *context = '\0';
01013          context++;
01014       } else
01015          context = oss.owner->context;
01016       if (ast_exists_extension(ast_bridged_channel(oss.owner), context, tmp, 1, ast_bridged_channel(oss.owner)->cid.cid_num)) {
01017          ast_cli(fd, "Whee, transferring %s to %s@%s.\n", 
01018                ast_bridged_channel(oss.owner)->name, tmp, context);
01019          if (ast_async_goto(ast_bridged_channel(oss.owner), context, tmp, 1))
01020             ast_cli(fd, "Failed to transfer :(\n");
01021       } else {
01022          ast_cli(fd, "No such extension exists\n");
01023       }
01024    } else {
01025       ast_cli(fd, "There is no call to transfer\n");
01026    }
01027    return RESULT_SUCCESS;
01028 }

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 1119 of file chan_oss_old.c.

01120 {
01121    return (char *) desc;
01122 }

char* key void   ) 
 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 1129 of file chan_oss_old.c.

References ASTERISK_GPL_KEY.

01130 {
01131    return ASTERISK_GPL_KEY;
01132 }

int load_module void   ) 
 

Initialize the module.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.

Definition at line 1045 of file chan_oss_old.c.

References ast_channel_register(), ast_cli_register(), ast_config_load(), ast_log(), ast_true(), ast_variable_browse(), ast_verbose(), autoanswer, cfg, full_duplex, LOG_ERROR, LOG_WARNING, myclis, ast_variable::name, ast_variable::next, option_verbose, oss_tech, sndcmd, soundcard_init(), ast_variable::value, and VERBOSE_PREFIX_2.

01046 {
01047    int res;
01048    int x;
01049    struct ast_config *cfg;
01050    struct ast_variable *v;
01051    res = pipe(sndcmd);
01052    if (res) {
01053       ast_log(LOG_ERROR, "Unable to create pipe\n");
01054       return -1;
01055    }
01056    res = soundcard_init();
01057    if (res < 0) {
01058       if (option_verbose > 1) {
01059          ast_verbose(VERBOSE_PREFIX_2 "No sound card detected -- console channel will be unavailable\n");
01060          ast_verbose(VERBOSE_PREFIX_2 "Turn off OSS support by adding 'noload=chan_oss.so' in /etc/asterisk/modules.conf\n");
01061       }
01062       return 0;
01063    }
01064    if (!full_duplex)
01065       ast_log(LOG_WARNING, "XXX I don't work right with non-full duplex sound cards XXX\n");
01066    res = ast_channel_register(&oss_tech);
01067    if (res < 0) {
01068       ast_log(LOG_ERROR, "Unable to register channel class '%s'\n", type);
01069       return -1;
01070    }
01071    for (x=0;x<sizeof(myclis)/sizeof(struct ast_cli_entry); x++)
01072       ast_cli_register(myclis + x);
01073    if ((cfg = ast_config_load(config))) {
01074       v = ast_variable_browse(cfg, "general");
01075       while(v) {
01076          if (!strcasecmp(v->name, "autoanswer"))
01077             autoanswer = ast_true(v->value);
01078          else if (!strcasecmp(v->name, "silencesuppression"))
01079             silencesuppression = ast_true(v->value);
01080          else if (!strcasecmp(v->name, "silencethreshold"))
01081             silencethreshold = atoi(v->value);
01082          else if (!strcasecmp(v->name, "context"))
01083             strncpy(context, v->value, sizeof(context)-1);
01084          else if (!strcasecmp(v->name, "language"))
01085             strncpy(language, v->value, sizeof(language)-1);
01086          else if (!strcasecmp(v->name, "extension"))
01087             strncpy(exten, v->value, sizeof(exten)-1);
01088          else if (!strcasecmp(v->name, "playbackonly"))
01089             playbackonly = ast_true(v->value);
01090          v=v->next;
01091       }
01092       ast_config_destroy(cfg);
01093    }
01094    ast_pthread_create(&sthread, NULL, sound_thread, NULL);
01095    return 0;
01096 }

static int oss_answer struct ast_channel c  )  [static]
 

Definition at line 540 of file chan_oss_old.c.

References answer_sound(), ast_setstate(), AST_STATE_UP, ast_verbose(), cursound, and nosound.

00541 {
00542    ast_verbose( " << Console call has been answered >> \n");
00543    answer_sound();
00544    ast_setstate(c, AST_STATE_UP);
00545    cursound = -1;
00546    nosound=0;
00547    return 0;
00548 }

static int oss_call struct ast_channel c,
char *  dest,
int  timeout
[static]
 

Definition at line 510 of file chan_oss_old.c.

References AST_CONTROL_ANSWER, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_queue_frame(), ast_verbose(), autoanswer, ast_frame::frametype, nosound, sndcmd, and ast_frame::subclass.

00511 {
00512    int res = 3;
00513    struct ast_frame f = { 0, };
00514    ast_verbose( " << Call placed to '%s' on console >> \n", dest);
00515    if (autoanswer) {
00516       ast_verbose( " << Auto-answered >> \n" );
00517       f.frametype = AST_FRAME_CONTROL;
00518       f.subclass = AST_CONTROL_ANSWER;
00519       ast_queue_frame(c, &f);
00520    } else {
00521       nosound = 1;
00522       ast_verbose( " << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
00523       f.frametype = AST_FRAME_CONTROL;
00524       f.subclass = AST_CONTROL_RINGING;
00525       ast_queue_frame(c, &f);
00526       write(sndcmd[1], &res, sizeof(res));
00527    }
00528    return 0;
00529 }

static int oss_digit struct ast_channel c,
char  digit
[static]
 

Definition at line 498 of file chan_oss_old.c.

References ast_verbose().

00499 {
00500    ast_verbose( " << Console Received digit %c >> \n", digit);
00501    return 0;
00502 }

static int oss_fixup struct ast_channel oldchan,
struct ast_channel newchan
[static]
 

Definition at line 729 of file chan_oss_old.c.

References chan_oss_pvt::owner, and ast_channel::tech_pvt.

00730 {
00731    struct chan_oss_pvt *p = newchan->tech_pvt;
00732    p->owner = newchan;
00733    return 0;
00734 }

static int oss_hangup struct ast_channel c  )  [static]
 

Definition at line 550 of file chan_oss_old.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), autoanswer, cursound, oss, chan_oss_pvt::owner, sndcmd, ast_channel::tech_pvt, and usecnt_lock.

00551 {
00552    int res = 0;
00553    cursound = -1;
00554    c->tech_pvt = NULL;
00555    oss.owner = NULL;
00556    ast_verbose( " << Hangup on console >> \n");
00557    ast_mutex_lock(&usecnt_lock);
00558    usecnt--;
00559    ast_mutex_unlock(&usecnt_lock);
00560    if (hookstate) {
00561       if (autoanswer) {
00562          /* Assume auto-hangup too */
00563          hookstate = 0;
00564       } else {
00565          /* Make congestion noise */
00566          res = 2;
00567          write(sndcmd[1], &res, sizeof(res));
00568          hookstate = 0;
00569       }
00570    }
00571    return 0;
00572 }

static int oss_indicate struct ast_channel chan,
int  cond
[static]
 

Definition at line 736 of file chan_oss_old.c.

References AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_RINGING, ast_log(), cursound, LOG_WARNING, ast_channel::name, and sndcmd.

00737 {
00738    int res;
00739    switch(cond) {
00740    case AST_CONTROL_BUSY:
00741       res = 1;
00742       break;
00743    case AST_CONTROL_CONGESTION:
00744       res = 2;
00745       break;
00746    case AST_CONTROL_RINGING:
00747       res = 0;
00748       break;
00749    case -1:
00750       cursound = -1;
00751       return 0;
00752    default:
00753       ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, chan->name);
00754       return -1;
00755    }
00756    if (res > -1) {
00757       write(sndcmd[1], &res, sizeof(res));
00758    }
00759    return 0;   
00760 }

static struct ast_channel* oss_new struct chan_oss_pvt p,
int  state
[static]
 

Definition at line 762 of file chan_oss_old.c.

References ast_channel_alloc(), AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_setstate(), AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), ast_channel::context, chan_oss_pvt::context, DEV_DSP, ast_channel::exten, chan_oss_pvt::exten, ast_channel::fds, ast_channel::language, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, oss_tech, chan_oss_pvt::owner, ast_channel::readformat, sounddev, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt_lock, and ast_channel::writeformat.

00763 {
00764    struct ast_channel *tmp;
00765    tmp = ast_channel_alloc(1);
00766    if (tmp) {
00767       tmp->tech = &oss_tech;
00768       snprintf(tmp->name, sizeof(tmp->name), "OSS/%s", DEV_DSP + 5);
00769       tmp->type = type;
00770       tmp->fds[0] = sounddev;
00771       tmp->nativeformats = AST_FORMAT_SLINEAR;
00772       tmp->readformat = AST_FORMAT_SLINEAR;
00773       tmp->writeformat = AST_FORMAT_SLINEAR;
00774       tmp->tech_pvt = p;
00775       if (!ast_strlen_zero(p->context))
00776          strncpy(tmp->context, p->context, sizeof(tmp->context)-1);
00777       if (!ast_strlen_zero(p->exten))
00778          strncpy(tmp->exten, p->exten, sizeof(tmp->exten)-1);
00779       if (!ast_strlen_zero(language))
00780          strncpy(tmp->language, language, sizeof(tmp->language)-1);
00781       p->owner = tmp;
00782       ast_setstate(tmp, state);
00783       ast_mutex_lock(&usecnt_lock);
00784       usecnt++;
00785       ast_mutex_unlock(&usecnt_lock);
00786       ast_update_use_count();
00787       if (state != AST_STATE_DOWN) {
00788          if (ast_pbx_start(tmp)) {
00789             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
00790             ast_hangup(tmp);
00791             tmp = NULL;
00792          }
00793       }
00794    }
00795    return tmp;
00796 }

static struct ast_frame * oss_read struct ast_channel chan  )  [static]
 

Definition at line 660 of file chan_oss_old.c.

References ast_channel::_state, AST_FORMAT_SLINEAR, AST_FRAME_NULL, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, CRASH, ast_frame::data, ast_frame::datalen, ast_frame::delivery, FRAME_SIZE, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, ast_frame::offset, ast_frame::samples, soundcard_setinput(), sounddev, ast_frame::src, and ast_frame::subclass.

00661 {
00662    static struct ast_frame f;
00663    static char buf[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];
00664    static int readpos = 0;
00665    int res;
00666    
00667 #if 0
00668    ast_log(LOG_DEBUG, "oss_read()\n");
00669 #endif
00670       
00671    f.frametype = AST_FRAME_NULL;
00672    f.subclass = 0;
00673    f.samples = 0;
00674    f.datalen = 0;
00675    f.data = NULL;
00676    f.offset = 0;
00677    f.src = type;
00678    f.mallocd = 0;
00679    f.delivery.tv_sec = 0;
00680    f.delivery.tv_usec = 0;
00681    
00682    res = soundcard_setinput(0);
00683    if (res < 0) {
00684       ast_log(LOG_WARNING, "Unable to set input mode\n");
00685       return NULL;
00686    }
00687    if (res > 0) {
00688       /* Theoretically shouldn't happen, but anyway, return a NULL frame */
00689       return &f;
00690    }
00691    res = read(sounddev, buf + AST_FRIENDLY_OFFSET + readpos, FRAME_SIZE * 2 - readpos);
00692    if (res < 0) {
00693       ast_log(LOG_WARNING, "Error reading from sound device (If you're running 'artsd' then kill it): %s\n", strerror(errno));
00694 #if 0
00695       CRASH;
00696 #endif      
00697       return NULL;
00698    }
00699    readpos += res;
00700    
00701    if (readpos >= FRAME_SIZE * 2) {
00702       /* A real frame */
00703       readpos = 0;
00704       if (chan->_state != AST_STATE_UP) {
00705          /* Don't transmit unless it's up */
00706          return &f;
00707       }
00708       f.frametype = AST_FRAME_VOICE;
00709       f.subclass = AST_FORMAT_SLINEAR;
00710       f.samples = FRAME_SIZE;
00711       f.datalen = FRAME_SIZE * 2;
00712       f.data = buf + AST_FRIENDLY_OFFSET;
00713       f.offset = AST_FRIENDLY_OFFSET;
00714       f.src = type;
00715       f.mallocd = 0;
00716       f.delivery.tv_sec = 0;
00717       f.delivery.tv_usec = 0;
00718 #if 0
00719       { static int fd = -1;
00720         if (fd < 0)
00721          fd = open("output.raw", O_RDWR | O_TRUNC | O_CREAT);
00722         write(fd, f.data, f.datalen);
00723       }
00724 #endif      
00725    }
00726    return &f;
00727 }

static struct ast_channel * oss_request const char *  type,
int  format,
void *  data,
int *  cause
[static]
 

Definition at line 798 of file chan_oss_old.c.

References AST_CAUSE_BUSY, AST_FORMAT_SLINEAR, ast_log(), AST_STATE_DOWN, LOG_NOTICE, LOG_WARNING, oss, oss_new(), and chan_oss_pvt::owner.

00799 {
00800    int oldformat = format;
00801    struct ast_channel *tmp;
00802    format &= AST_FORMAT_SLINEAR;
00803    if (!format) {
00804       ast_log(LOG_NOTICE, "Asked to get a channel of format '%d'\n", oldformat);
00805       return NULL;
00806    }
00807    if (oss.owner) {
00808       ast_log(LOG_NOTICE, "Already have a call on the OSS channel\n");
00809       *cause = AST_CAUSE_BUSY;
00810       return NULL;
00811    }
00812    tmp= oss_new(&oss, AST_STATE_DOWN);
00813    if (!tmp) {
00814       ast_log(LOG_WARNING, "Unable to create new OSS channel\n");
00815    }
00816    return tmp;
00817 }

static int oss_text struct ast_channel c,
const char *  text
[static]
 

Definition at line 504 of file chan_oss_old.c.

References ast_verbose().

00505 {
00506    ast_verbose( " << Console Received text %s >> \n", text);
00507    return 0;
00508 }

static int oss_write struct ast_channel chan,
struct ast_frame f
[static]
 

Definition at line 609 of file chan_oss_old.c.

References ast_log(), cursound, ast_frame::data, ast_frame::datalen, FRAME_SIZE, full_duplex, LOG_WARNING, nosound, soundcard_setinput(), soundcard_setoutput(), and soundcard_writeframe().

00610 {
00611    int res;
00612    static char sizbuf[8000];
00613    static int sizpos = 0;
00614    int len = sizpos;
00615    int pos;
00616    /* Immediately return if no sound is enabled */
00617    if (nosound)
00618       return 0;
00619    /* Stop any currently playing sound */
00620    cursound = -1;
00621    if (!full_duplex && !playbackonly) {
00622       /* If we're half duplex, we have to switch to read mode
00623          to honor immediate needs if necessary.  But if we are in play
00624          back only mode, then we don't switch because the console
00625          is only being used one way -- just to playback something. */
00626       res = soundcard_setinput(1);
00627       if (res < 0) {
00628          ast_log(LOG_WARNING, "Unable to set device to input mode\n");
00629          return -1;
00630       }
00631       return 0;
00632    }
00633    res = soundcard_setoutput(0);
00634    if (res < 0) {
00635       ast_log(LOG_WARNING, "Unable to set output device\n");
00636       return -1;
00637    } else if (res > 0) {
00638       /* The device is still in read mode, and it's too soon to change it,
00639          so just pretend we wrote it */
00640       return 0;
00641    }
00642    /* We have to digest the frame in 160-byte portions */
00643    if (f->datalen > sizeof(sizbuf) - sizpos) {
00644       ast_log(LOG_WARNING, "Frame too large\n");
00645       return -1;
00646    }
00647    memcpy(sizbuf + sizpos, f->data, f->datalen);
00648    len += f->datalen;
00649    pos = 0;
00650    while(len - pos > FRAME_SIZE * 2) {
00651       soundcard_writeframe((short *)(sizbuf + pos));
00652       pos += FRAME_SIZE * 2;
00653    }
00654    if (len - pos) 
00655       memmove(sizbuf, sizbuf + pos, len - pos);
00656    sizpos = len - pos;
00657    return 0;
00658 }

static int send_sound void   )  [static]
 

Definition at line 217 of file chan_oss_old.c.

References ast_log(), sound::datalen, FRAME_SIZE, LOG_WARNING, sound::silencelen, sounddev, sounds, and total.

00218 {
00219    short myframe[FRAME_SIZE];
00220    int total = FRAME_SIZE;
00221    short *frame = NULL;
00222    int amt=0;
00223    int res;
00224    int myoff;
00225    audio_buf_info abi;
00226    if (cursound > -1) {
00227       res = ioctl(sounddev, SNDCTL_DSP_GETOSPACE ,&abi);
00228       if (res) {
00229          ast_log(LOG_WARNING, "Unable to read output space\n");
00230          return -1;
00231       }
00232       /* Calculate how many samples we can send, max */
00233       if (total > (abi.fragments * abi.fragsize / 2)) 
00234          total = abi.fragments * abi.fragsize / 2;
00235       res = total;
00236       if (sampsent < sounds[cursound].samplen) {
00237          myoff=0;
00238          while(total) {
00239             amt = total;
00240             if (amt > (sounds[cursound].datalen - offset)) 
00241                amt = sounds[cursound].datalen - offset;
00242             memcpy(myframe + myoff, sounds[cursound].data + offset, amt * 2);
00243             total -= amt;
00244             offset += amt;
00245             sampsent += amt;
00246             myoff += amt;
00247             if (offset >= sounds[cursound].datalen)
00248                offset = 0;
00249          }
00250          /* Set it up for silence */
00251          if (sampsent >= sounds[cursound].samplen) 
00252             silencelen = sounds[cursound].silencelen;
00253          frame = myframe;
00254       } else {
00255          if (silencelen > 0) {
00256             frame = silence;
00257             silencelen -= res;
00258          } else {
00259             if (sounds[cursound].repeat) {
00260                /* Start over */
00261                sampsent = 0;
00262                offset = 0;
00263             } else {
00264                cursound = -1;
00265                nosound = 0;
00266             }
00267          }
00268       }
00269       if (frame)
00270          res = write(sounddev, frame, res * 2);
00271       if (res > 0)
00272          return 0;
00273       return res;
00274    }
00275    return 0;
00276 }

static int setformat void   )  [static]
 

Definition at line 367 of file chan_oss_old.c.

References ast_log(), ast_verbose(), BUFFER_FMT, fmt, full_duplex, LOG_WARNING, option_verbose, sounddev, and VERBOSE_PREFIX_2.

00368 {
00369    int fmt, desired, res, fd = sounddev;
00370    static int warnedalready = 0;
00371    static int warnedalready2 = 0;
00372 
00373 #if __BYTE_ORDER == __LITTLE_ENDIAN
00374    fmt = AFMT_S16_LE;
00375 #else
00376    fmt = AFMT_S16_BE;
00377 #endif
00378 
00379    res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
00380    if (res < 0) {
00381       ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n");
00382       return -1;
00383    }
00384    res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
00385    
00386    /* Check to see if duplex set (FreeBSD Bug)*/
00387    res = ioctl(fd, SNDCTL_DSP_GETCAPS, &fmt);
00388    
00389    if ((fmt & DSP_CAP_DUPLEX) && !res) {
00390       if (option_verbose > 1) 
00391          ast_verbose(VERBOSE_PREFIX_2 "Console is full duplex\n");
00392       full_duplex = -1;
00393    }
00394    fmt = 0;
00395    res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
00396    if (res < 0) {
00397       ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
00398       return -1;
00399    }
00400    /* 8000 Hz desired */
00401    desired = 8000;
00402    fmt = desired;
00403    res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
00404    if (res < 0) {
00405       ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
00406       return -1;
00407    }
00408    if (fmt != desired) {
00409       if (!warnedalready++)
00410          ast_log(LOG_WARNING, "Requested %d Hz, got %d Hz -- sound may be choppy\n", desired, fmt);
00411    }
00412 #if 1
00413    fmt = BUFFER_FMT;
00414    res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt);
00415    if (res < 0) {
00416       if (!warnedalready2++)
00417          ast_log(LOG_WARNING, "Unable to set fragment size -- sound may be choppy\n");
00418    }
00419 #endif
00420    return 0;
00421 }

static void* sound_thread void *  unused  )  [static]
 

Definition at line 278 of file chan_oss_old.c.

References ast_log(), ast_select(), LOG_WARNING, oss, chan_oss_pvt::owner, send_sound(), sndcmd, and sounddev.

00279 {
00280    fd_set rfds;
00281    fd_set wfds;
00282    int max;
00283    int res;
00284    char ign[4096];
00285    if (read(sounddev, ign, sizeof(sounddev)) < 0)
00286       ast_log(LOG_WARNING, "Read error on sound device: %s\n", strerror(errno));
00287    for(;;) {
00288       FD_ZERO(&rfds);
00289       FD_ZERO(&wfds);
00290       max = sndcmd[0];
00291       FD_SET(sndcmd[0], &rfds);
00292       if (!oss.owner) {
00293          FD_SET(sounddev, &rfds);
00294          if (sounddev > max)
00295             max = sounddev;
00296       }
00297       if (cursound > -1) {
00298          FD_SET(sounddev, &wfds);
00299          if (sounddev > max)
00300             max = sounddev;
00301       }
00302       res = ast_select(max + 1, &rfds, &wfds, NULL, NULL);
00303       if (res < 1) {
00304          ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
00305          continue;
00306       }
00307       if (FD_ISSET(sndcmd[0], &rfds)) {
00308          read(sndcmd[0], &cursound, sizeof(cursound));
00309          silencelen = 0;
00310          offset = 0;
00311          sampsent = 0;
00312       }
00313       if (FD_ISSET(sounddev, &rfds)) {
00314          /* Ignore read */
00315          if (read(sounddev, ign, sizeof(ign)) < 0)
00316             ast_log(LOG_WARNING, "Read error on sound device: %s\n", strerror(errno));
00317       }
00318       if (FD_ISSET(sounddev, &wfds))
00319          if (send_sound())
00320             ast_log(LOG_WARNING, "Failed to write sound\n");
00321    }
00322    /* Never reached */
00323    return NULL;
00324 }

static int soundcard_init void   )  [static]
 

Definition at line 482 of file chan_oss_old.c.

References ast_log(), DEV_DSP, full_duplex, LOG_WARNING, setformat(), soundcard_setinput(), and sounddev.

00483 {
00484    /* Assume it's full duplex for starters */
00485    int fd = open(DEV_DSP,  O_RDWR | O_NONBLOCK);
00486    if (fd < 0) {
00487       ast_log(LOG_WARNING, "Unable to open %s: %s\n", DEV_DSP, strerror(errno));
00488       return fd;
00489    }
00490    gettimeofday(&lasttime, NULL);
00491    sounddev = fd;
00492    setformat();
00493    if (!full_duplex) 
00494       soundcard_setinput(1);
00495    return sounddev;
00496 }

static int soundcard_setinput int  force  )  [static]
 

Definition at line 454 of file chan_oss_old.c.

References ast_log(), DEV_DSP, full_duplex, LOG_WARNING, readmode, setformat(), sounddev, and time_has_passed().

Referenced by oss_read(), oss_write(), and soundcard_init().

00455 {
00456    int fd = sounddev;
00457    if (full_duplex || (readmode && !force))
00458       return 0;
00459    readmode = -1;
00460    if (force || time_has_passed()) {
00461       ioctl(sounddev, SNDCTL_DSP_RESET, 0);
00462       close(sounddev);
00463       /* dup2(0, sound); */
00464       fd = open(DEV_DSP, O_RDONLY | O_NONBLOCK);
00465       if (fd < 0) {
00466          ast_log(LOG_WARNING, "Unable to re-open DSP device: %s\n", strerror(errno));
00467          return -1;
00468       }
00469       /* dup2 will close the original and make fd be sound */
00470       if (dup2(fd, sounddev) < 0) {
00471          ast_log(LOG_WARNING, "dup2() failed: %s\n", strerror(errno));
00472          return -1;
00473       }
00474       if (setformat()) {
00475          return -1;
00476       }
00477       return 0;
00478    }
00479    return 1;
00480 }

static int soundcard_setoutput int  force  )  [static]
 

Definition at line 423 of file chan_oss_old.c.

References ast_log(), DEV_DSP, full_duplex, LOG_WARNING, readmode, setformat(), sounddev, and time_has_passed().

Referenced by oss_write().

00424 {
00425    /* Make sure the soundcard is in output mode.  */
00426    int fd = sounddev;
00427    if (full_duplex || (!readmode && !force))
00428       return 0;
00429    readmode = 0;
00430    if (force || time_has_passed()) {
00431       ioctl(sounddev, SNDCTL_DSP_RESET, 0);
00432       /* Keep the same fd reserved by closing the sound device and copying stdin at the same
00433          time. */
00434       /* dup2(0, sound); */ 
00435       close(sounddev);
00436       fd = open(DEV_DSP, O_WRONLY |O_NONBLOCK);
00437       if (fd < 0) {
00438          ast_log(LOG_WARNING, "Unable to re-open DSP device: %s\n", strerror(errno));
00439          return -1;
00440       }
00441       /* dup2 will close the original and make fd be sound */
00442       if (dup2(fd, sounddev) < 0) {
00443          ast_log(LOG_WARNING, "dup2() failed: %s\n", strerror(errno));
00444          return -1;
00445       }
00446       if (setformat()) {
00447          return -1;
00448       }
00449       return 0;
00450    }
00451    return 1;
00452 }

static int soundcard_writeframe short *  data  )  [static]
 

Definition at line 574 of file chan_oss_old.c.

References ast_log(), buffersize, FRAME_SIZE, LOG_WARNING, MAX_BUFFER_SIZE, and sounddev.

00575 {  
00576    /* Write an exactly FRAME_SIZE sized of frame */
00577    static int bufcnt = 0;
00578    static short buffer[FRAME_SIZE * MAX_BUFFER_SIZE * 5];
00579    struct audio_buf_info info;
00580    int res;
00581    int fd = sounddev;
00582    static int warned=0;
00583    if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info)) {
00584       if (!warned)
00585          ast_log(LOG_WARNING, "Error reading output space\n");
00586       bufcnt = buffersize;
00587       warned++;
00588    }
00589    if ((info.fragments >= buffersize * 5) && (bufcnt == buffersize)) {
00590       /* We've run out of stuff, buffer again */
00591       bufcnt = 0;
00592    }
00593    if (bufcnt == buffersize) {
00594       /* Write sample immediately */
00595       res = write(fd, ((void *)data), FRAME_SIZE * 2);
00596    } else {
00597       /* Copy the data into our buffer */
00598       res = FRAME_SIZE * 2;
00599       memcpy(buffer + (bufcnt * FRAME_SIZE), data, FRAME_SIZE * 2);
00600       bufcnt++;
00601       if (bufcnt == buffersize) {
00602          res = write(fd, ((void *)buffer), FRAME_SIZE * 2 * buffersize);
00603       }
00604    }
00605    return res;
00606 }

static int time_has_passed void   )  [static]
 

Definition at line 164 of file chan_oss_old.c.

References MIN_SWITCH_TIME.

Referenced by soundcard_setinput(), and soundcard_setoutput().

00165 {
00166    struct timeval tv;
00167    int ms;
00168    gettimeofday(&tv, NULL);
00169    ms = (tv.tv_sec - lasttime.tv_sec) * 1000 +
00170          (tv.tv_usec - lasttime.tv_usec) / 1000;
00171    if (ms > MIN_SWITCH_TIME)
00172       return -1;
00173    return 0;
00174 }

int unload_module void   ) 
 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
Zero on success, or non-zero on error.

Definition at line 1100 of file chan_oss_old.c.

References ast_channel_unregister(), ast_cli_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, myclis, oss, oss_tech, chan_oss_pvt::owner, sndcmd, and sounddev.

01101 {
01102    int x;
01103 
01104    ast_channel_unregister(&oss_tech);
01105    for (x=0;x<sizeof(myclis)/sizeof(struct ast_cli_entry); x++)
01106       ast_cli_unregister(myclis + x);
01107    close(sounddev);
01108    if (sndcmd[0] > 0) {
01109       close(sndcmd[0]);
01110       close(sndcmd[1]);
01111    }
01112    if (oss.owner)
01113       ast_softhangup(oss.owner, AST_SOFTHANGUP_APPUNLOAD);
01114    if (oss.owner)
01115       return -1;
01116    return 0;
01117 }

int usecount void   ) 
 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 1124 of file chan_oss_old.c.

01125 {
01126    return usecnt;
01127 }


Variable Documentation

char answer_usage[] [static]
 

Initial value:

"Usage: answer\n"
"       Answers an incoming call on the console (OSS) channel.\n"

Definition at line 909 of file chan_oss_old.c.

int autoanswer = 1 [static]
 

Definition at line 193 of file chan_oss_old.c.

char autoanswer_usage[] [static]
 

Initial value:

"Usage: autoanswer [on|off]\n"
"       Enables or disables autoanswer feature.  If used without\n"
"       argument, displays the current on/off status of autoanswer.\n"
"       The default value of autoanswer is in 'oss.conf'.\n"

Definition at line 855 of file chan_oss_old.c.

int buffersize = 3 [static]
 

Definition at line 183 of file chan_oss_old.c.

Referenced by soundcard_writeframe().

const char config[] = "oss.conf" [static]
 

Definition at line 99 of file chan_oss_old.c.

char context[AST_MAX_CONTEXT] = "default" [static]
 

Definition at line 101 of file chan_oss_old.c.

int cursound = -1 [static]
 

Definition at line 211 of file chan_oss_old.c.

const char desc[] = "OSS Console Channel Driver" [static]
 

Definition at line 97 of file chan_oss_old.c.

char dial_usage[] [static]
 

Initial value:

"Usage: dial [extension[@context]]\n"
"       Dials a given extensison (and context if specified)\n"

Definition at line 998 of file chan_oss_old.c.

char exten[AST_MAX_EXTENSION] = "s" [static]
 

Definition at line 103 of file chan_oss_old.c.

char flash_usage[] [static]
 

Initial value:

"Usage: flash\n"
"       Flashes the call currently placed on the console.\n"

Definition at line 951 of file chan_oss_old.c.

int full_duplex = 0 [static]
 

Definition at line 185 of file chan_oss_old.c.

Referenced by load_module(), oss_write(), setformat(), soundcard_init(), soundcard_setinput(), and soundcard_setoutput().

char hangup_usage[] [static]
 

Initial value:

"Usage: hangup\n"
"       Hangs up any call currently placed on the console.\n"

Definition at line 946 of file chan_oss_old.c.

int hookstate = 0 [static]
 

Definition at line 105 of file chan_oss_old.c.

char language[MAX_LANGUAGE] = "" [static]
 

Definition at line 102 of file chan_oss_old.c.

struct timeval lasttime [static]
 

Definition at line 86 of file chan_oss_old.c.

struct ast_cli_entry myclis[] [static]
 

Definition at line 1035 of file chan_oss_old.c.

int nosound = 0 [static]
 

Definition at line 215 of file chan_oss_old.c.

int offset = 0 [static]
 

Definition at line 214 of file chan_oss_old.c.

struct chan_oss_pvt oss [static]
 

Referenced by console_answer(), console_dial(), console_flash(), console_hangup(), console_sendtext(), console_transfer(), oss_hangup(), oss_request(), sound_thread(), and unload_module().

const struct ast_channel_tech oss_tech [static]
 

Definition at line 148 of file chan_oss_old.c.

int playbackonly = 0 [static]
 

Definition at line 91 of file chan_oss_old.c.

int readmode = 1 [static]
 

Definition at line 188 of file chan_oss_old.c.

Referenced by soundcard_setinput(), and soundcard_setoutput().

int sampsent = 0 [static]
 

Definition at line 212 of file chan_oss_old.c.

char sendtext_usage[] [static]
 

Initial value:

"Usage: send text <message>\n"
"       Sends a text message for display on the remote terminal.\n"

Definition at line 877 of file chan_oss_old.c.

short silence[FRAME_SIZE] = {0, } [static]
 

Definition at line 107 of file chan_oss_old.c.

int silencelen = 0 [static]
 

Definition at line 213 of file chan_oss_old.c.

int silencesuppression = 0 [static]
 

Definition at line 89 of file chan_oss_old.c.

int silencethreshold = 1000 [static]
 

Definition at line 90 of file chan_oss_old.c.

int sndcmd[2] [static]
 

Definition at line 127 of file chan_oss_old.c.

int sounddev = -1 [static]
 

Definition at line 191 of file chan_oss_old.c.

Referenced by oss_new(), oss_read(), send_sound(), setformat(), sound_thread(), soundcard_init(), soundcard_setinput(), soundcard_setoutput(), soundcard_writeframe(), and unload_module().

struct sound sounds[] [static]
 

Definition at line 118 of file chan_oss_old.c.

pthread_t sthread [static]
 

Definition at line 180 of file chan_oss_old.c.

const char tdesc[] = "OSS Console Channel Driver" [static]
 

Definition at line 98 of file chan_oss_old.c.

char transfer_usage[] [static]
 

Initial value:

"Usage: transfer <extension>[@context]\n"
"       Transfers the currently connected call to the given extension (and\n"
"context if specified)\n"

Definition at line 1030 of file chan_oss_old.c.

const char type[] = "Console" [static]
 

Definition at line 96 of file chan_oss_old.c.

int usecnt [static]
 

Definition at line 88 of file chan_oss_old.c.


Generated on Fri May 26 01:47:00 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.6