Tue Apr 6 15:45:48 2010

Asterisk developer's documentation


chan_oss.c File Reference

Channel driver for OSS sound cards. More...

#include "asterisk.h"
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/time.h>
#include <stdlib.h>
#include <errno.h>
#include <soundcard.h>
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/logger.h"
#include "asterisk/callerid.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 "asterisk/stringfields.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/musiconhold.h"
#include "busy_tone.h"
#include "ring_tone.h"
#include "ring10.h"
#include "answer.h"

Go to the source code of this file.

Data Structures

struct  chan_oss_pvt
struct  sound

Defines

#define BOOST_MAX   40
#define BOOST_SCALE   (1<<9)
#define DEV_DSP   "/dev/dsp"
#define FRAGS   ( ( (6 * 5) << 16 ) | 0x6 )
#define FRAME_SIZE   160
#define M_BOOL(tag, dst)   M_F(tag, (dst) = ast_true(__val) )
#define M_END(x)   x;
#define M_F(tag, f)   if (!strcasecmp((__s), tag)) { f; } else
#define M_START(var, val)   char *__s = var; char *__val = val;
#define M_STR(tag, dst)   M_F(tag, ast_copy_string(dst, __val, sizeof(dst)))
#define M_UINT(tag, dst)   M_F(tag, (dst) = strtoul(__val, NULL, 0) )
#define MAX(a, b)   ((a) > (b) ? (a) : (b))
#define MIN(a, b)   ((a) < (b) ? (a) : (b))
#define O_CLOSE   0x444
#define QUEUE_SIZE   10
#define TEXT_SIZE   256
#define WARN_frag   4
#define WARN_speed   2
#define WARN_used_blocks   1

Functions

static int __console_mute_unmute (int mute)
static void __reg_module (void)
static void __unreg_module (void)
static char * ast_ext_ctx (const char *src, char **ext, char **ctx)
static char * autoanswer_complete (const char *line, const char *word, int pos, int state)
static char * autoanswer_complete_deprecated (const char *line, const char *word, int pos, int state)
static int console_active (int fd, int argc, char *argv[])
static int console_active_deprecated (int fd, int argc, char *argv[])
static int console_answer (int fd, int argc, char *argv[])
static int console_answer_deprecated (int fd, int argc, char *argv[])
static int console_autoanswer (int fd, int argc, char *argv[])
static int console_autoanswer_deprecated (int fd, int argc, char *argv[])
static int console_dial (int fd, int argc, char *argv[])
static int console_dial_deprecated (int fd, int argc, char *argv[])
static int console_flash (int fd, int argc, char *argv[])
static int console_flash_deprecated (int fd, int argc, char *argv[])
static int console_hangup (int fd, int argc, char *argv[])
static int console_hangup_deprecated (int fd, int argc, char *argv[])
static int console_mute (int fd, int argc, char *argv[])
static int console_mute_deprecated (int fd, int argc, char *argv[])
static int console_sendtext (int fd, int argc, char *argv[])
static int console_sendtext_deprecated (int fd, int argc, char *argv[])
static int console_transfer (int fd, int argc, char *argv[])
static int console_transfer_deprecated (int fd, int argc, char *argv[])
static int console_unmute (int fd, int argc, char *argv[])
static int console_unmute_deprecated (int fd, int argc, char *argv[])
static int do_boost (int fd, int argc, char *argv[])
static struct chan_oss_pvtfind_desc (char *dev)
static int load_module (void)
static int oss_answer (struct ast_channel *c)
static int oss_call (struct ast_channel *c, char *dest, int timeout)
static int oss_digit_begin (struct ast_channel *c, char digit)
static int oss_digit_end (struct ast_channel *c, char digit, unsigned int duration)
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, const void *data, size_t datalen)
static struct ast_channeloss_new (struct chan_oss_pvt *o, char *ext, char *ctx, 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 void ring (struct chan_oss_pvt *o, int x)
static void send_sound (struct chan_oss_pvt *o)
static int setformat (struct chan_oss_pvt *o, int mode)
static void * sound_thread (void *arg)
static int soundcard_writeframe (struct chan_oss_pvt *o, short *data)
static void store_boost (struct chan_oss_pvt *o, char *s)
static void store_callerid (struct chan_oss_pvt *o, char *s)
static struct chan_oss_pvtstore_config (struct ast_config *cfg, char *ctg)
static void store_mixer (struct chan_oss_pvt *o, char *s)
static int unload_module (void)
static int used_blocks (struct chan_oss_pvt *o)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "OSS Console Channel Driver" , .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 char active_usage []
static char answer_usage []
static const struct ast_module_infoast_module_info = &__mod_info
static char autoanswer_usage []
static struct ast_cli_entry cli_oss []
static struct ast_cli_entry cli_oss_active_deprecated
static struct ast_cli_entry cli_oss_answer_deprecated
static struct ast_cli_entry cli_oss_autoanswer_deprecated
static struct ast_cli_entry cli_oss_boost_deprecated
static struct ast_cli_entry cli_oss_dial_deprecated
static struct ast_cli_entry cli_oss_flash_deprecated
static struct ast_cli_entry cli_oss_hangup_deprecated
static struct ast_cli_entry cli_oss_mute_deprecated
static struct ast_cli_entry cli_oss_send_text_deprecated
static struct ast_cli_entry cli_oss_transfer_deprecated
static struct ast_cli_entry cli_oss_unmute_deprecated
static char * config = "oss.conf"
static struct ast_jb_conf default_jbconf
static char dial_usage []
static char flash_usage []
static struct ast_jb_conf global_jbconf
static char hangup_usage []
static char mute_usage []
static char * oss_active
static int oss_debug
static struct chan_oss_pvt oss_default
static struct ast_channel_tech oss_tech
static char sendtext_usage []
static struct sound sounds []
static char tdesc [] = "OSS Console Channel Driver"
static char transfer_usage []
static char unmute_usage []


Detailed Description

Channel driver for OSS sound cards.

Author:
Mark Spencer <markster@digium.com>

Luigi Rizzo

See also

Definition in file chan_oss.c.


Define Documentation

#define BOOST_MAX   40

Definition at line 360 of file chan_oss.c.

Referenced by store_boost().

#define BOOST_SCALE   (1<<9)

Definition at line 359 of file chan_oss.c.

Referenced by do_boost(), oss_read(), and store_boost().

#define DEV_DSP   "/dev/dsp"

Definition at line 274 of file chan_oss.c.

Referenced by store_config().

#define FRAGS   ( ( (6 * 5) << 16 ) | 0x6 )

Definition at line 257 of file chan_oss.c.

#define FRAME_SIZE   160

Definition at line 251 of file chan_oss.c.

#define M_BOOL ( tag,
dst   )     M_F(tag, (dst) = ast_true(__val) )

Definition at line 217 of file chan_oss.c.

Referenced by store_config().

#define M_END (  )     x;

Definition at line 215 of file chan_oss.c.

Referenced by store_config().

#define M_F ( tag,
f   )     if (!strcasecmp((__s), tag)) { f; } else

Definition at line 216 of file chan_oss.c.

Referenced by store_config().

#define M_START ( var,
val   )     char *__s = var; char *__val = val;

Definition at line 213 of file chan_oss.c.

Referenced by store_config().

#define M_STR ( tag,
dst   )     M_F(tag, ast_copy_string(dst, __val, sizeof(dst)))

Definition at line 219 of file chan_oss.c.

Referenced by store_config().

#define M_UINT ( tag,
dst   )     M_F(tag, (dst) = strtoul(__val, NULL, 0) )

Definition at line 218 of file chan_oss.c.

Referenced by store_config().

#define MAX ( a,
 )     ((a) > (b) ? (a) : (b))

Definition at line 281 of file chan_oss.c.

Referenced by handle_response_register(), openserial(), and sound_thread().

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

Definition at line 278 of file chan_oss.c.

#define O_CLOSE   0x444

Definition at line 269 of file chan_oss.c.

Referenced by console_hangup(), console_hangup_deprecated(), oss_hangup(), setformat(), and sound_thread().

#define QUEUE_SIZE   10

Definition at line 252 of file chan_oss.c.

#define TEXT_SIZE   256

Definition at line 264 of file chan_oss.c.

Referenced by console_sendtext(), and console_sendtext_deprecated().

#define WARN_frag   4

Definition at line 349 of file chan_oss.c.

Referenced by setformat().

#define WARN_speed   2

Definition at line 348 of file chan_oss.c.

Referenced by setformat().

#define WARN_used_blocks   1

Definition at line 347 of file chan_oss.c.

Referenced by used_blocks().


Function Documentation

static int __console_mute_unmute ( int  mute  )  [static]

Definition at line 1412 of file chan_oss.c.

References find_desc(), chan_oss_pvt::mute, oss_active, and RESULT_SUCCESS.

Referenced by console_mute(), console_mute_deprecated(), console_unmute(), and console_unmute_deprecated().

01413 {
01414    struct chan_oss_pvt *o = find_desc(oss_active);
01415    
01416    o->mute = mute;
01417    return RESULT_SUCCESS;
01418 }

static void __reg_module ( void   )  [static]

Definition at line 1898 of file chan_oss.c.

static void __unreg_module ( void   )  [static]

Definition at line 1898 of file chan_oss.c.

static char* ast_ext_ctx ( const char *  src,
char **  ext,
char **  ctx 
) [static]

Definition at line 461 of file chan_oss.c.

References ast_strdup, find_desc(), and chan_oss_pvt::overridecontext.

Referenced by console_dial(), console_dial_deprecated(), console_transfer(), and console_transfer_deprecated().

00462 {
00463    struct chan_oss_pvt *o = find_desc(oss_active);
00464 
00465    if (ext == NULL || ctx == NULL)
00466       return NULL;         /* error */
00467 
00468    *ext = *ctx = NULL;
00469 
00470    if (src && *src != '\0')
00471       *ext = ast_strdup(src);
00472 
00473    if (*ext == NULL)
00474       return NULL;
00475 
00476    if (!o->overridecontext) {
00477       /* parse from the right */
00478       *ctx = strrchr(*ext, '@');
00479       if (*ctx)
00480          *(*ctx)++ = '\0';
00481    }
00482 
00483    return *ext;
00484 }

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

Definition at line 1120 of file chan_oss.c.

References ast_cli_complete().

01121 {
01122    static char *choices[] = { "on", "off", NULL };
01123 
01124    return (pos != 3) ? NULL : ast_cli_complete(word, choices, state);
01125 }

static char* autoanswer_complete_deprecated ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 1113 of file chan_oss.c.

References ast_cli_complete().

01114 {
01115    static char *choices[] = { "on", "off", NULL };
01116 
01117    return (pos != 2) ? NULL : ast_cli_complete(word, choices, state);
01118 }

static int console_active ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1546 of file chan_oss.c.

References ast_cli(), find_desc(), chan_oss_pvt::name, chan_oss_pvt::next, oss_active, oss_default, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01547 {
01548    if (argc == 2)
01549       ast_cli(fd, "active console is [%s]\n", oss_active);
01550    else if (argc != 3)
01551       return RESULT_SHOWUSAGE;
01552    else {
01553       struct chan_oss_pvt *o;
01554       if (strcmp(argv[2], "show") == 0) {
01555          for (o = oss_default.next; o; o = o->next)
01556             ast_cli(fd, "device [%s] exists\n", o->name);
01557          return RESULT_SUCCESS;
01558       }
01559       o = find_desc(argv[2]);
01560       if (o == NULL)
01561          ast_cli(fd, "No device [%s] exists\n", argv[2]);
01562       else
01563          oss_active = o->name;
01564    }
01565    return RESULT_SUCCESS;
01566 }

static int console_active_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1524 of file chan_oss.c.

References ast_cli(), find_desc(), chan_oss_pvt::name, chan_oss_pvt::next, oss_active, oss_default, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01525 {
01526    if (argc == 1)
01527       ast_cli(fd, "active console is [%s]\n", oss_active);
01528    else if (argc != 2)
01529       return RESULT_SHOWUSAGE;
01530    else {
01531       struct chan_oss_pvt *o;
01532       if (strcmp(argv[1], "show") == 0) {
01533          for (o = oss_default.next; o; o = o->next)
01534             ast_cli(fd, "device [%s] exists\n", o->name);
01535          return RESULT_SUCCESS;
01536       }
01537       o = find_desc(argv[1]);
01538       if (o == NULL)
01539          ast_cli(fd, "No device [%s] exists\n", argv[1]);
01540       else
01541          oss_active = o->name;
01542    }
01543    return RESULT_SUCCESS;
01544 }

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

Definition at line 1158 of file chan_oss.c.

References ast_cli(), AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_queue_frame(), chan_oss_pvt::cursound, f, find_desc(), chan_oss_pvt::hookstate, chan_oss_pvt::nosound, oss_active, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ring().

01159 {
01160    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
01161    struct chan_oss_pvt *o = find_desc(oss_active);
01162 
01163    if (argc != 2)
01164       return RESULT_SHOWUSAGE;
01165    if (!o->owner) {
01166       ast_cli(fd, "No one is calling us\n");
01167       return RESULT_FAILURE;
01168    }
01169    o->hookstate = 1;
01170    o->cursound = -1;
01171    o->nosound = 0;
01172    ast_queue_frame(o->owner, &f);
01173 #if 0
01174    /* XXX do we really need it ? considering we shut down immediately... */
01175    ring(o, AST_CONTROL_ANSWER);
01176 #endif
01177    return RESULT_SUCCESS;
01178 }

static int console_answer_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1136 of file chan_oss.c.

References ast_cli(), AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_queue_frame(), chan_oss_pvt::cursound, f, find_desc(), chan_oss_pvt::hookstate, chan_oss_pvt::nosound, oss_active, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and ring().

01137 {
01138    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
01139    struct chan_oss_pvt *o = find_desc(oss_active);
01140 
01141    if (argc != 1)
01142       return RESULT_SHOWUSAGE;
01143    if (!o->owner) {
01144       ast_cli(fd, "No one is calling us\n");
01145       return RESULT_FAILURE;
01146    }
01147    o->hookstate = 1;
01148    o->cursound = -1;
01149    o->nosound = 0;
01150    ast_queue_frame(o->owner, &f);
01151 #if 0
01152    /* XXX do we really need it ? considering we shut down immediately... */
01153    ring(o, AST_CONTROL_ANSWER);
01154 #endif
01155    return RESULT_SUCCESS;
01156 }

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

Definition at line 1089 of file chan_oss.c.

References ast_cli(), ast_log(), chan_oss_pvt::autoanswer, find_desc(), LOG_WARNING, oss_active, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01090 {
01091    struct chan_oss_pvt *o = find_desc(oss_active);
01092 
01093    if (argc == 2) {
01094       ast_cli(fd, "Auto answer is %s.\n", o->autoanswer ? "on" : "off");
01095       return RESULT_SUCCESS;
01096    }
01097    if (argc != 3)
01098       return RESULT_SHOWUSAGE;
01099    if (o == NULL) {
01100       ast_log(LOG_WARNING, "Cannot find device %s (should not happen!)\n",
01101           oss_active);
01102       return RESULT_FAILURE;
01103    }
01104    if (!strcasecmp(argv[2], "on"))
01105       o->autoanswer = -1;
01106    else if (!strcasecmp(argv[2], "off"))
01107       o->autoanswer = 0;
01108    else
01109       return RESULT_SHOWUSAGE;
01110    return RESULT_SUCCESS;
01111 }

static int console_autoanswer_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1066 of file chan_oss.c.

References ast_cli(), ast_log(), chan_oss_pvt::autoanswer, find_desc(), LOG_WARNING, oss_active, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01067 {
01068    struct chan_oss_pvt *o = find_desc(oss_active);
01069 
01070    if (argc == 1) {
01071       ast_cli(fd, "Auto answer is %s.\n", o->autoanswer ? "on" : "off");
01072       return RESULT_SUCCESS;
01073    }
01074    if (argc != 2)
01075       return RESULT_SHOWUSAGE;
01076    if (o == NULL) {
01077       ast_log(LOG_WARNING, "Cannot find device %s (should not happen!)\n", oss_active);
01078       return RESULT_FAILURE;
01079    }
01080    if (!strcasecmp(argv[1], "on"))
01081       o->autoanswer = -1;
01082    else if (!strcasecmp(argv[1], "off"))
01083       o->autoanswer = 0;
01084    else
01085       return RESULT_SHOWUSAGE;
01086    return RESULT_SUCCESS;
01087 }

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

Definition at line 1367 of file chan_oss.c.

References ast_cli(), ast_exists_extension(), ast_ext_ctx(), AST_FRAME_DTMF, ast_queue_frame(), AST_STATE_RINGING, chan_oss_pvt::ctx, chan_oss_pvt::ext, f, find_desc(), free, chan_oss_pvt::hookstate, oss_active, oss_new(), chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and s.

01368 {
01369    char *s = NULL, *mye = NULL, *myc = NULL;
01370    struct chan_oss_pvt *o = find_desc(oss_active);
01371 
01372    if (argc != 2 && argc != 3)
01373       return RESULT_SHOWUSAGE;
01374    if (o->owner) {   /* already in a call */
01375       int i;
01376       struct ast_frame f = { AST_FRAME_DTMF, 0 };
01377 
01378       if (argc == 2) {  /* argument is mandatory here */
01379          ast_cli(fd, "Already in a call. You can only dial digits until you hangup.\n");
01380          return RESULT_FAILURE;
01381       }
01382       s = argv[2];
01383       /* send the string one char at a time */
01384       for (i = 0; i < strlen(s); i++) {
01385          f.subclass = s[i];
01386          ast_queue_frame(o->owner, &f);
01387       }
01388       return RESULT_SUCCESS;
01389    }
01390    /* if we have an argument split it into extension and context */
01391    if (argc == 3)
01392       s = ast_ext_ctx(argv[2], &mye, &myc);
01393    /* supply default values if needed */
01394    if (mye == NULL)
01395       mye = o->ext;
01396    if (myc == NULL)
01397       myc = o->ctx;
01398    if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
01399       o->hookstate = 1;
01400       oss_new(o, mye, myc, AST_STATE_RINGING);
01401    } else
01402       ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
01403    if (s)
01404       free(s);
01405    return RESULT_SUCCESS;
01406 }

static int console_dial_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1326 of file chan_oss.c.

References ast_cli(), ast_exists_extension(), ast_ext_ctx(), AST_FRAME_DTMF, ast_queue_frame(), AST_STATE_RINGING, chan_oss_pvt::ctx, chan_oss_pvt::ext, f, find_desc(), free, chan_oss_pvt::hookstate, oss_active, oss_new(), chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and s.

01327 {
01328    char *s = NULL, *mye = NULL, *myc = NULL;
01329    struct chan_oss_pvt *o = find_desc(oss_active);
01330 
01331    if (argc != 1 && argc != 2)
01332       return RESULT_SHOWUSAGE;
01333    if (o->owner) { /* already in a call */
01334       int i;
01335       struct ast_frame f = { AST_FRAME_DTMF, 0 };
01336 
01337       if (argc == 1) { /* argument is mandatory here */
01338          ast_cli(fd, "Already in a call. You can only dial digits until you hangup.\n");
01339          return RESULT_FAILURE;
01340       }
01341       s = argv[1];
01342       /* send the string one char at a time */
01343       for (i = 0; i < strlen(s); i++) {
01344          f.subclass = s[i];
01345          ast_queue_frame(o->owner, &f);
01346       }
01347       return RESULT_SUCCESS;
01348    }
01349    /* if we have an argument split it into extension and context */
01350    if (argc == 2)
01351       s = ast_ext_ctx(argv[1], &mye, &myc);
01352    /* supply default values if needed */
01353    if (mye == NULL)
01354       mye = o->ext;
01355    if (myc == NULL)
01356       myc = o->ctx;
01357    if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
01358       o->hookstate = 1;
01359       oss_new(o, mye, myc, AST_STATE_RINGING);
01360    } else
01361       ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
01362    if (s)
01363       free(s);
01364    return RESULT_SUCCESS;
01365 }

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

Definition at line 1303 of file chan_oss.c.

References ast_cli(), AST_CONTROL_FLASH, AST_FRAME_CONTROL, ast_queue_frame(), chan_oss_pvt::cursound, f, find_desc(), chan_oss_pvt::hookstate, chan_oss_pvt::nosound, oss_active, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01304 {
01305    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH };
01306    struct chan_oss_pvt *o = find_desc(oss_active);
01307 
01308    if (argc != 2)
01309       return RESULT_SHOWUSAGE;
01310    o->cursound = -1;
01311    o->nosound = 0;            /* when cursound is -1 nosound must be 0 */
01312    if (!o->owner) {        /* XXX maybe !o->hookstate too ? */
01313       ast_cli(fd, "No call to flash\n");
01314       return RESULT_FAILURE;
01315    }
01316    o->hookstate = 0;
01317    if (o->owner)
01318       ast_queue_frame(o->owner, &f);
01319    return RESULT_SUCCESS;
01320 }

static int console_flash_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1284 of file chan_oss.c.

References ast_cli(), AST_CONTROL_FLASH, AST_FRAME_CONTROL, ast_queue_frame(), chan_oss_pvt::cursound, f, find_desc(), chan_oss_pvt::hookstate, chan_oss_pvt::nosound, oss_active, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01285 {
01286    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH };
01287    struct chan_oss_pvt *o = find_desc(oss_active);
01288 
01289    if (argc != 1)
01290       return RESULT_SHOWUSAGE;
01291    o->cursound = -1;
01292    o->nosound = 0; /* when cursound is -1 nosound must be 0 */
01293    if (!o->owner) { /* XXX maybe !o->hookstate too ? */
01294       ast_cli(fd, "No call to flash\n");
01295       return RESULT_FAILURE;
01296    }
01297    o->hookstate = 0;
01298    if (o->owner)
01299       ast_queue_frame(o->owner, &f);
01300    return RESULT_SUCCESS;
01301 }

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

Definition at line 1261 of file chan_oss.c.

References ast_cli(), ast_queue_hangup(), chan_oss_pvt::cursound, find_desc(), chan_oss_pvt::hookstate, chan_oss_pvt::nosound, O_CLOSE, oss_active, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and setformat().

01262 {
01263    struct chan_oss_pvt *o = find_desc(oss_active);
01264 
01265    if (argc != 2)
01266       return RESULT_SHOWUSAGE;
01267    o->cursound = -1;
01268    o->nosound = 0;
01269    if (!o->owner && !o->hookstate) { /* XXX maybe only one ? */
01270       ast_cli(fd, "No call to hang up\n");
01271       return RESULT_FAILURE;
01272    }
01273    o->hookstate = 0;
01274    if (o->owner)
01275       ast_queue_hangup(o->owner);
01276    setformat(o, O_CLOSE);
01277    return RESULT_SUCCESS;
01278 }

static int console_hangup_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1242 of file chan_oss.c.

References ast_cli(), ast_queue_hangup(), chan_oss_pvt::cursound, find_desc(), chan_oss_pvt::hookstate, chan_oss_pvt::nosound, O_CLOSE, oss_active, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and setformat().

01243 {
01244    struct chan_oss_pvt *o = find_desc(oss_active);
01245 
01246    if (argc != 1)
01247       return RESULT_SHOWUSAGE;
01248    o->cursound = -1;
01249    o->nosound = 0;
01250    if (!o->owner && !o->hookstate) { /* XXX maybe only one ? */
01251       ast_cli(fd, "No call to hang up\n");
01252       return RESULT_FAILURE;
01253    }
01254    o->hookstate = 0;
01255    if (o->owner)
01256       ast_queue_hangup(o->owner);
01257    setformat(o, O_CLOSE);
01258    return RESULT_SUCCESS;
01259 }

static int console_mute ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1428 of file chan_oss.c.

References __console_mute_unmute(), and RESULT_SHOWUSAGE.

01429 {
01430    if (argc != 2)
01431       return RESULT_SHOWUSAGE;
01432 
01433    return __console_mute_unmute(1);
01434 }

static int console_mute_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1420 of file chan_oss.c.

References __console_mute_unmute(), and RESULT_SHOWUSAGE.

01421 {
01422    if (argc != 1)
01423       return RESULT_SHOWUSAGE;
01424 
01425    return __console_mute_unmute(1);
01426 }

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

Definition at line 1213 of file chan_oss.c.

References ast_cli(), AST_FRAME_TEXT, ast_join(), ast_queue_frame(), ast_strlen_zero(), f, find_desc(), oss_active, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and TEXT_SIZE.

01214 {
01215    struct chan_oss_pvt *o = find_desc(oss_active);
01216    char buf[TEXT_SIZE];
01217 
01218    if (argc < 3)
01219       return RESULT_SHOWUSAGE;
01220    if (!o->owner) {
01221       ast_cli(fd, "Not in a call\n");
01222       return RESULT_FAILURE;
01223    }
01224    ast_join(buf, sizeof(buf) - 1, argv + 3);
01225    if (!ast_strlen_zero(buf)) {
01226       struct ast_frame f = { 0, };
01227       int i = strlen(buf);
01228       buf[i] = '\n';
01229       f.frametype = AST_FRAME_TEXT;
01230       f.subclass = 0;
01231       f.data = buf;
01232       f.datalen = i + 1;
01233       ast_queue_frame(o->owner, &f);
01234    }
01235    return RESULT_SUCCESS;
01236 }

static int console_sendtext_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1188 of file chan_oss.c.

References ast_cli(), AST_FRAME_TEXT, ast_join(), ast_queue_frame(), ast_strlen_zero(), f, find_desc(), oss_active, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and TEXT_SIZE.

01189 {
01190    struct chan_oss_pvt *o = find_desc(oss_active);
01191    char buf[TEXT_SIZE];
01192 
01193    if (argc < 2)
01194       return RESULT_SHOWUSAGE;
01195    if (!o->owner) {
01196       ast_cli(fd, "Not in a call\n");
01197       return RESULT_FAILURE;
01198    }
01199    ast_join(buf, sizeof(buf) - 1, argv + 2);
01200    if (!ast_strlen_zero(buf)) {
01201       struct ast_frame f = { 0, };
01202       int i = strlen(buf);
01203       buf[i] = '\n';
01204       f.frametype = AST_FRAME_TEXT;
01205       f.subclass = 0;
01206       f.data = buf;
01207       f.datalen = i + 1;
01208       ast_queue_frame(o->owner, &f);
01209    }
01210    return RESULT_SUCCESS;
01211 }

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

Definition at line 1489 of file chan_oss.c.

References ast_async_goto(), ast_bridged_channel(), ast_cli(), ast_exists_extension(), ast_ext_ctx(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ext, find_desc(), free, ast_channel::name, oss_active, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01490 {
01491    struct chan_oss_pvt *o = find_desc(oss_active);
01492    struct ast_channel *b = NULL;
01493    char *tmp, *ext, *ctx;
01494 
01495    if (argc != 3)
01496       return RESULT_SHOWUSAGE;
01497    if (o == NULL)
01498       return RESULT_FAILURE;
01499    if (o->owner == NULL || (b = ast_bridged_channel(o->owner)) == NULL) {
01500       ast_cli(fd, "There is no call to transfer\n");
01501       return RESULT_SUCCESS;
01502    }
01503 
01504    tmp = ast_ext_ctx(argv[2], &ext, &ctx);
01505    if (ctx == NULL)        /* supply default context if needed */
01506       ctx = o->owner->context;
01507    if (!ast_exists_extension(b, ctx, ext, 1, b->cid.cid_num))
01508       ast_cli(fd, "No such extension exists\n");
01509    else {
01510       ast_cli(fd, "Whee, transferring %s to %s@%s.\n", b->name, ext, ctx);
01511       if (ast_async_goto(b, ctx, ext, 1))
01512          ast_cli(fd, "Failed to transfer :(\n");
01513    }
01514    if (tmp)
01515       free(tmp);
01516    return RESULT_SUCCESS;
01517 }

static int console_transfer_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1458 of file chan_oss.c.

References ast_async_goto(), ast_bridged_channel(), ast_cli(), ast_exists_extension(), ast_ext_ctx(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ext, find_desc(), free, ast_channel::name, oss_active, chan_oss_pvt::owner, RESULT_FAILURE, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01459 {
01460    struct chan_oss_pvt *o = find_desc(oss_active);
01461    struct ast_channel *b = NULL;
01462    char *tmp, *ext, *ctx;
01463 
01464    if (argc != 2)
01465       return RESULT_SHOWUSAGE;
01466    if (o == NULL)
01467       return RESULT_FAILURE;
01468    if (o->owner ==NULL || (b = ast_bridged_channel(o->owner)) == NULL) {
01469       ast_cli(fd, "There is no call to transfer\n");
01470       return RESULT_SUCCESS;
01471    }
01472 
01473    tmp = ast_ext_ctx(argv[1], &ext, &ctx);
01474    if (ctx == NULL)     /* supply default context if needed */
01475       ctx = o->owner->context;
01476    if (!ast_exists_extension(b, ctx, ext, 1, b->cid.cid_num))
01477       ast_cli(fd, "No such extension exists\n");
01478    else {
01479       ast_cli(fd, "Whee, transferring %s to %s@%s.\n",
01480          b->name, ext, ctx);
01481       if (ast_async_goto(b, ctx, ext, 1))
01482          ast_cli(fd, "Failed to transfer :(\n");
01483    }
01484    if (tmp)
01485       free(tmp);
01486    return RESULT_SUCCESS;
01487 }

static int console_unmute ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1447 of file chan_oss.c.

References __console_mute_unmute(), and RESULT_SHOWUSAGE.

01448 {
01449    if (argc != 2)
01450       return RESULT_SHOWUSAGE;
01451 
01452    return __console_mute_unmute(0);
01453 }

static int console_unmute_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1439 of file chan_oss.c.

References __console_mute_unmute(), and RESULT_SHOWUSAGE.

01440 {
01441    if (argc != 1)
01442       return RESULT_SHOWUSAGE;
01443 
01444    return __console_mute_unmute(0);
01445 }

static int do_boost ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1596 of file chan_oss.c.

References ast_cli(), chan_oss_pvt::boost, BOOST_SCALE, find_desc(), oss_active, RESULT_SUCCESS, and store_boost().

01597 {
01598    struct chan_oss_pvt *o = find_desc(oss_active);
01599 
01600    if (argc == 2)
01601       ast_cli(fd, "boost currently %5.1f\n", 20 * log10(((double) o->boost / (double) BOOST_SCALE)));
01602    else if (argc == 3)
01603       store_boost(o, argv[2]);
01604    return RESULT_SUCCESS;
01605 }

static struct chan_oss_pvt* find_desc ( char *  dev  )  [static]

Definition at line 437 of file chan_oss.c.

References ast_log(), LOG_WARNING, chan_oss_pvt::name, chan_oss_pvt::next, and oss_default.

Referenced by __console_mute_unmute(), ast_ext_ctx(), console_active(), console_active_deprecated(), console_answer(), console_answer_deprecated(), console_autoanswer(), console_autoanswer_deprecated(), console_dial(), console_dial_deprecated(), console_flash(), console_flash_deprecated(), console_hangup(), console_hangup_deprecated(), console_sendtext(), console_sendtext_deprecated(), console_transfer(), console_transfer_deprecated(), do_boost(), load_module(), and oss_request().

00438 {
00439    struct chan_oss_pvt *o = NULL;
00440 
00441    if (!dev)
00442       ast_log(LOG_WARNING, "null dev\n");
00443 
00444    for (o = oss_default.next; o && o->name && dev && strcmp(o->name, dev) != 0; o = o->next);
00445 
00446    if (!o)
00447       ast_log(LOG_WARNING, "could not find <%s>\n", dev ? dev : "--no-device--");
00448 
00449    return o;
00450 }

static int load_module ( void   )  [static]

Definition at line 1837 of file chan_oss.c.

References ast_category_browse(), ast_channel_register(), ast_cli_register_multiple(), ast_config_destroy(), ast_config_load(), ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, cli_oss, default_jbconf, find_desc(), global_jbconf, LOG_ERROR, LOG_NOTICE, oss_active, oss_tech, and store_config().

01838 {
01839    struct ast_config *cfg = NULL;
01840    char *ctg = NULL;
01841 
01842    /* Copy the default jb config over global_jbconf */
01843    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
01844 
01845    /* load config file */
01846    if (!(cfg = ast_config_load(config))) {
01847       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
01848       return AST_MODULE_LOAD_DECLINE;
01849    }
01850 
01851    do {
01852       store_config(cfg, ctg);
01853    } while ( (ctg = ast_category_browse(cfg, ctg)) != NULL);
01854 
01855    ast_config_destroy(cfg);
01856 
01857    if (find_desc(oss_active) == NULL) {
01858       ast_log(LOG_NOTICE, "Device %s not found\n", oss_active);
01859       /* XXX we could default to 'dsp' perhaps ? */
01860       /* XXX should cleanup allocated memory etc. */
01861       return AST_MODULE_LOAD_FAILURE;
01862    }
01863 
01864    if (ast_channel_register(&oss_tech)) {
01865       ast_log(LOG_ERROR, "Unable to register channel type 'OSS'\n");
01866       return AST_MODULE_LOAD_FAILURE;
01867    }
01868 
01869    ast_cli_register_multiple(cli_oss, sizeof(cli_oss) / sizeof(struct ast_cli_entry));
01870 
01871    return AST_MODULE_LOAD_SUCCESS;
01872 }

static int oss_answer ( struct ast_channel c  )  [static]

Definition at line 824 of file chan_oss.c.

References AST_CONTROL_ANSWER, ast_setstate(), AST_STATE_UP, ast_verbose(), chan_oss_pvt::cursound, chan_oss_pvt::hookstate, chan_oss_pvt::nosound, ring(), and ast_channel::tech_pvt.

00825 {
00826    struct chan_oss_pvt *o = c->tech_pvt;
00827 
00828    ast_verbose(" << Console call has been answered >> \n");
00829 #if 0
00830    /* play an answer tone (XXX do we really need it ?) */
00831    ring(o, AST_CONTROL_ANSWER);
00832 #endif
00833    ast_setstate(c, AST_STATE_UP);
00834    o->cursound = -1;
00835    o->nosound = 0;
00836    o->hookstate = 1;
00837    return 0;
00838 }

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

Definition at line 799 of file chan_oss.c.

References AST_CONTROL_ANSWER, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_queue_frame(), ast_verbose(), chan_oss_pvt::autoanswer, ast_channel::cid, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_rdnis, f, chan_oss_pvt::hookstate, ring(), and ast_channel::tech_pvt.

00800 {
00801    struct chan_oss_pvt *o = c->tech_pvt;
00802    struct ast_frame f = { 0, };
00803 
00804    ast_verbose(" << Call to device '%s' dnid '%s' rdnis '%s' on console from '%s' <%s> >>\n", dest, c->cid.cid_dnid, c->cid.cid_rdnis, c->cid.cid_name, c->cid.cid_num);
00805    if (o->autoanswer) {
00806       ast_verbose(" << Auto-answered >> \n");
00807       f.frametype = AST_FRAME_CONTROL;
00808       f.subclass = AST_CONTROL_ANSWER;
00809       ast_queue_frame(c, &f);
00810       o->hookstate = 1;
00811    } else {
00812       ast_verbose("<< Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
00813       f.frametype = AST_FRAME_CONTROL;
00814       f.subclass = AST_CONTROL_RINGING;
00815       ast_queue_frame(c, &f);
00816       ring(o, AST_CONTROL_RING);
00817    }
00818    return 0;
00819 }

static int oss_digit_begin ( struct ast_channel c,
char  digit 
) [static]

Definition at line 767 of file chan_oss.c.

00768 {
00769    return 0;
00770 }

static int oss_digit_end ( struct ast_channel c,
char  digit,
unsigned int  duration 
) [static]

Definition at line 772 of file chan_oss.c.

References ast_verbose().

00773 {
00774    /* no better use for received digits than print them */
00775    ast_verbose(" << Console Received digit %c of duration %u ms >> \n", 
00776       digit, duration);
00777    return 0;
00778 }

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

Definition at line 949 of file chan_oss.c.

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

00950 {
00951    struct chan_oss_pvt *o = newchan->tech_pvt;
00952    o->owner = newchan;
00953    return 0;
00954 }

static int oss_hangup ( struct ast_channel c  )  [static]

Definition at line 840 of file chan_oss.c.

References AST_CONTROL_CONGESTION, ast_module_unref(), ast_verbose(), chan_oss_pvt::autoanswer, chan_oss_pvt::autohangup, chan_oss_pvt::cursound, chan_oss_pvt::hookstate, chan_oss_pvt::nosound, O_CLOSE, chan_oss_pvt::owner, ring(), setformat(), and ast_channel::tech_pvt.

00841 {
00842    struct chan_oss_pvt *o = c->tech_pvt;
00843 
00844    o->cursound = -1;
00845    o->nosound = 0;
00846    c->tech_pvt = NULL;
00847    o->owner = NULL;
00848    ast_verbose(" << Hangup on console >> \n");
00849    ast_module_unref(ast_module_info->self);
00850    if (o->hookstate) {
00851       if (o->autoanswer || o->autohangup) {
00852          /* Assume auto-hangup too */
00853          o->hookstate = 0;
00854          setformat(o, O_CLOSE);
00855       } else {
00856          /* Make congestion noise */
00857          ring(o, AST_CONTROL_CONGESTION);
00858       }
00859    }
00860    return 0;
00861 }

static int oss_indicate ( struct ast_channel chan,
int  cond,
const void *  data,
size_t  datalen 
) [static]

Definition at line 956 of file chan_oss.c.

References AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_verbose(), chan_oss_pvt::cursound, LOG_WARNING, chan_oss_pvt::mohinterpret, ast_channel::name, chan_oss_pvt::nosound, ring(), and ast_channel::tech_pvt.

00957 {
00958    struct chan_oss_pvt *o = c->tech_pvt;
00959    int res = -1;
00960 
00961    switch (cond) {
00962    case AST_CONTROL_BUSY:
00963    case AST_CONTROL_CONGESTION:
00964    case AST_CONTROL_RINGING:
00965          res = cond;
00966          break;
00967          
00968    case -1:
00969       o->cursound = -1;
00970       o->nosound = 0;      /* when cursound is -1 nosound must be 0 */
00971       return 0;
00972       
00973    case AST_CONTROL_VIDUPDATE:
00974       res = -1;
00975       break;
00976    case AST_CONTROL_HOLD:
00977       ast_verbose(" << Console Has Been Placed on Hold >> \n");
00978       ast_moh_start(c, data, o->mohinterpret);
00979          break;
00980    case AST_CONTROL_UNHOLD:
00981       ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
00982       ast_moh_stop(c);
00983       break;
00984    case AST_CONTROL_SRCUPDATE:
00985       break;
00986    default:
00987       ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, c->name);
00988       return -1;
00989    }
00990 
00991    if (res > -1)
00992       ring(o, res);
00993 
00994    return 0;
00995 }

static struct ast_channel* oss_new ( struct chan_oss_pvt o,
char *  ext,
char *  ctx,
int  state 
) [static]

Definition at line 1000 of file chan_oss.c.

References ast_channel_alloc(), AST_FORMAT_SLINEAR, ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, chan_oss_pvt::cid_name, chan_oss_pvt::cid_num, chan_oss_pvt::device, ast_channel::fds, global_jbconf, language, chan_oss_pvt::language, LOG_WARNING, ast_channel::nativeformats, oss_tech, chan_oss_pvt::owner, ast_channel::readformat, setformat(), chan_oss_pvt::sounddev, ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat.

Referenced by console_dial(), console_dial_deprecated(), and oss_request().

01001 {
01002    struct ast_channel *c;
01003 
01004    c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, 0, "Console/%s", o->device + 5);
01005    if (c == NULL)
01006       return NULL;
01007    c->tech = &oss_tech;
01008    if (o->sounddev < 0)
01009       setformat(o, O_RDWR);
01010    c->fds[0] = o->sounddev;   /* -1 if device closed, override later */
01011    c->nativeformats = AST_FORMAT_SLINEAR;
01012    c->readformat = AST_FORMAT_SLINEAR;
01013    c->writeformat = AST_FORMAT_SLINEAR;
01014    c->tech_pvt = o;
01015 
01016    if (!ast_strlen_zero(o->language))
01017       ast_string_field_set(c, language, o->language);
01018    /* Don't use ast_set_callerid() here because it will
01019     * generate a needless NewCallerID event */
01020    c->cid.cid_ani = ast_strdup(o->cid_num);
01021    if (!ast_strlen_zero(ext))
01022       c->cid.cid_dnid = ast_strdup(ext);
01023 
01024    o->owner = c;
01025    ast_module_ref(ast_module_info->self);
01026    ast_jb_configure(c, &global_jbconf);
01027    if (state != AST_STATE_DOWN) {
01028       if (ast_pbx_start(c)) {
01029          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", c->name);
01030          ast_hangup(c);
01031          o->owner = c = NULL;
01032       }
01033    }
01034 
01035    return c;
01036 }

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

Definition at line 900 of file chan_oss.c.

References ast_channel::_state, AST_FORMAT_SLINEAR, AST_FRAME_NULL, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, AST_STATE_UP, chan_oss_pvt::boost, BOOST_SCALE, f, FRAME_SIZE, chan_oss_pvt::mute, chan_oss_pvt::oss_read_buf, oss_tech, chan_oss_pvt::read_f, chan_oss_pvt::readpos, chan_oss_pvt::sounddev, ast_channel::tech_pvt, and ast_channel_tech::type.

00901 {
00902    int res;
00903    struct chan_oss_pvt *o = c->tech_pvt;
00904    struct ast_frame *f = &o->read_f;
00905 
00906    /* XXX can be simplified returning &ast_null_frame */
00907    /* prepare a NULL frame in case we don't have enough data to return */
00908    bzero(f, sizeof(struct ast_frame));
00909    f->frametype = AST_FRAME_NULL;
00910    f->src = oss_tech.type;
00911 
00912    res = read(o->sounddev, o->oss_read_buf + o->readpos, sizeof(o->oss_read_buf) - o->readpos);
00913    if (res < 0)            /* audio data not ready, return a NULL frame */
00914       return f;
00915 
00916    o->readpos += res;
00917    if (o->readpos < sizeof(o->oss_read_buf)) /* not enough samples */
00918       return f;
00919 
00920    if (o->mute)
00921       return f;
00922 
00923    o->readpos = AST_FRIENDLY_OFFSET;   /* reset read pointer for next frame */
00924    if (c->_state != AST_STATE_UP)   /* drop data if frame is not up */
00925       return f;
00926    /* ok we can build and deliver the frame to the caller */
00927    f->frametype = AST_FRAME_VOICE;
00928    f->subclass = AST_FORMAT_SLINEAR;
00929    f->samples = FRAME_SIZE;
00930    f->datalen = FRAME_SIZE * 2;
00931    f->data = o->oss_read_buf + AST_FRIENDLY_OFFSET;
00932    if (o->boost != BOOST_SCALE) {   /* scale and clip values */
00933       int i, x;
00934       int16_t *p = (int16_t *) f->data;
00935       for (i = 0; i < f->samples; i++) {
00936          x = (p[i] * o->boost) / BOOST_SCALE;
00937          if (x > 32767)
00938             x = 32767;
00939          else if (x < -32768)
00940             x = -32768;
00941          p[i] = x;
00942       }
00943    }
00944 
00945    f->offset = AST_FRIENDLY_OFFSET;
00946    return f;
00947 }

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

Definition at line 1038 of file chan_oss.c.

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

01039 {
01040    struct ast_channel *c;
01041    struct chan_oss_pvt *o = find_desc(data);
01042 
01043    ast_log(LOG_WARNING, "oss_request ty <%s> data 0x%p <%s>\n", type, data, (char *) data);
01044    if (o == NULL) {
01045       ast_log(LOG_NOTICE, "Device %s not found\n", (char *) data);
01046       /* XXX we could default to 'dsp' perhaps ? */
01047       return NULL;
01048    }
01049    if ((format & AST_FORMAT_SLINEAR) == 0) {
01050       ast_log(LOG_NOTICE, "Format 0x%x unsupported\n", format);
01051       return NULL;
01052    }
01053    if (o->owner) {
01054       ast_log(LOG_NOTICE, "Already have a call (chan %p) on the OSS channel\n", o->owner);
01055       *cause = AST_CAUSE_BUSY;
01056       return NULL;
01057    }
01058    c = oss_new(o, NULL, NULL, AST_STATE_DOWN);
01059    if (c == NULL) {
01060       ast_log(LOG_WARNING, "Unable to create new OSS channel\n");
01061       return NULL;
01062    }
01063    return c;
01064 }

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

Definition at line 780 of file chan_oss.c.

References ast_verbose().

00781 {
00782    /* print received messages */
00783    ast_verbose(" << Console Received text %s >> \n", text);
00784    return 0;
00785 }

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

Definition at line 864 of file chan_oss.c.

References chan_oss_pvt::cursound, f, chan_oss_pvt::nosound, chan_oss_pvt::oss_write_buf, chan_oss_pvt::oss_write_dst, soundcard_writeframe(), and ast_channel::tech_pvt.

00865 {
00866    int src;
00867    struct chan_oss_pvt *o = c->tech_pvt;
00868 
00869    /* Immediately return if no sound is enabled */
00870    if (o->nosound)
00871       return 0;
00872    /* Stop any currently playing sound */
00873    o->cursound = -1;
00874    /*
00875     * we could receive a block which is not a multiple of our
00876     * FRAME_SIZE, so buffer it locally and write to the device
00877     * in FRAME_SIZE chunks.
00878     * Keep the residue stored for future use.
00879     */
00880    src = 0;             /* read position into f->data */
00881    while (src < f->datalen) {
00882       /* Compute spare room in the buffer */
00883       int l = sizeof(o->oss_write_buf) - o->oss_write_dst;
00884 
00885       if (f->datalen - src >= l) {  /* enough to fill a frame */
00886          memcpy(o->oss_write_buf + o->oss_write_dst, f->data + src, l);
00887          soundcard_writeframe(o, (short *) o->oss_write_buf);
00888          src += l;
00889          o->oss_write_dst = 0;
00890       } else {          /* copy residue */
00891          l = f->datalen - src;
00892          memcpy(o->oss_write_buf + o->oss_write_dst, f->data + src, l);
00893          src += l;         /* but really, we are done */
00894          o->oss_write_dst += l;
00895       }
00896    }
00897    return 0;
00898 }

static void ring ( struct chan_oss_pvt o,
int  x 
) [static]

Definition at line 788 of file chan_oss.c.

References ast_log(), errno, LOG_WARNING, and chan_oss_pvt::sndcmd.

Referenced by console_answer(), console_answer_deprecated(), ind_load_module(), oss_answer(), oss_call(), oss_hangup(), and oss_indicate().

00789 {
00790    if (write(o->sndcmd[1], &x, sizeof(x)) < 0) {
00791       ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
00792    }
00793 }

static void send_sound ( struct chan_oss_pvt o  )  [static]

Definition at line 545 of file chan_oss.c.

References ast_log(), chan_oss_pvt::cursound, FRAME_SIZE, LOG_WARNING, chan_oss_pvt::nosound, s, chan_oss_pvt::sampsent, silence, soundcard_writeframe(), and sounds.

00546 {
00547    short myframe[FRAME_SIZE];
00548    int ofs, l, start;
00549    int l_sampsent = o->sampsent;
00550    struct sound *s;
00551 
00552    if (o->cursound < 0)    /* no sound to send */
00553       return;
00554 
00555    s = &sounds[o->cursound];
00556 
00557    for (ofs = 0; ofs < FRAME_SIZE; ofs += l) {
00558       l = s->samplen - l_sampsent;  /* # of available samples */
00559       if (l > 0) {
00560          start = l_sampsent % s->datalen; /* source offset */
00561          if (l > FRAME_SIZE - ofs)  /* don't overflow the frame */
00562             l = FRAME_SIZE - ofs;
00563          if (l > s->datalen - start)   /* don't overflow the source */
00564             l = s->datalen - start;
00565          bcopy(s->data + start, myframe + ofs, l * 2);
00566          if (0)
00567             ast_log(LOG_WARNING, "send_sound sound %d/%d of %d into %d\n", l_sampsent, l, s->samplen, ofs);
00568          l_sampsent += l;
00569       } else {          /* end of samples, maybe some silence */
00570          static const short silence[FRAME_SIZE] = { 0, };
00571 
00572          l += s->silencelen;
00573          if (l > 0) {
00574             if (l > FRAME_SIZE - ofs)
00575                l = FRAME_SIZE - ofs;
00576             bcopy(silence, myframe + ofs, l * 2);
00577             l_sampsent += l;
00578          } else {       /* silence is over, restart sound if loop */
00579             if (s->repeat == 0) {   /* last block */
00580                o->cursound = -1;
00581                o->nosound = 0;   /* allow audio data */
00582                if (ofs < FRAME_SIZE)   /* pad with silence */
00583                   bcopy(silence, myframe + ofs, (FRAME_SIZE - ofs) * 2);
00584             }
00585             l_sampsent = 0;
00586          }
00587       }
00588    }
00589    l = soundcard_writeframe(o, myframe);
00590    if (l > 0)
00591       o->sampsent = l_sampsent;  /* update status */
00592 }

static int setformat ( struct chan_oss_pvt o,
int  mode 
) [static]

Definition at line 669 of file chan_oss.c.

References ast_log(), ast_tvdiff_ms(), ast_tvnow(), ast_verbose(), DEFAULT_SAMPLE_RATE, chan_oss_pvt::device, chan_oss_pvt::duplex, errno, ast_channel::fds, chan_oss_pvt::frags, chan_oss_pvt::lastopen, LOG_WARNING, chan_oss_pvt::M_FULL, chan_oss_pvt::M_READ, chan_oss_pvt::M_UNSET, chan_oss_pvt::M_WRITE, O_CLOSE, option_verbose, chan_oss_pvt::owner, chan_oss_pvt::sounddev, VERBOSE_PREFIX_2, WARN_frag, WARN_speed, and chan_oss_pvt::warned.

Referenced by console_hangup(), console_hangup_deprecated(), oss_hangup(), oss_new(), sound_thread(), and soundcard_writeframe().

00670 {
00671    int fmt, desired, res, fd;
00672 
00673    if (o->sounddev >= 0) {
00674       ioctl(o->sounddev, SNDCTL_DSP_RESET, 0);
00675       close(o->sounddev);
00676       o->duplex = M_UNSET;
00677       o->sounddev = -1;
00678    }
00679    if (mode == O_CLOSE)    /* we are done */
00680       return 0;
00681    if (ast_tvdiff_ms(ast_tvnow(), o->lastopen) < 1000)
00682       return -1;           /* don't open too often */
00683    o->lastopen = ast_tvnow();
00684    fd = o->sounddev = open(o->device, mode | O_NONBLOCK);
00685    if (fd < 0) {
00686       ast_log(LOG_WARNING, "Unable to re-open DSP device %s: %s\n", o->device, strerror(errno));
00687       return -1;
00688    }
00689    if (o->owner)
00690       o->owner->fds[0] = fd;
00691 
00692 #if __BYTE_ORDER == __LITTLE_ENDIAN
00693    fmt = AFMT_S16_LE;
00694 #else
00695    fmt = AFMT_S16_BE;
00696 #endif
00697    res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
00698    if (res < 0) {
00699       ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n");
00700       return -1;
00701    }
00702    switch (mode) {
00703       case O_RDWR:
00704          res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
00705          /* Check to see if duplex set (FreeBSD Bug) */
00706          res = ioctl(fd, SNDCTL_DSP_GETCAPS, &fmt);
00707          if (res == 0 && (fmt & DSP_CAP_DUPLEX)) {
00708             if (option_verbose > 1)
00709                ast_verbose(VERBOSE_PREFIX_2 "Console is full duplex\n");
00710             o->duplex = M_FULL;
00711          };
00712          break;
00713       case O_WRONLY:
00714          o->duplex = M_WRITE;
00715          break;
00716       case O_RDONLY:
00717          o->duplex = M_READ;
00718          break;
00719    }
00720 
00721    fmt = 0;
00722    res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
00723    if (res < 0) {
00724       ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
00725       return -1;
00726    }
00727    fmt = desired = DEFAULT_SAMPLE_RATE;   /* 8000 Hz desired */
00728    res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
00729 
00730    if (res < 0) {
00731       ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
00732       return -1;
00733    }
00734    if (fmt != desired) {
00735       if (!(o->warned & WARN_speed)) {
00736          ast_log(LOG_WARNING,
00737              "Requested %d Hz, got %d Hz -- sound may be choppy\n",
00738              desired, fmt);
00739          o->warned |= WARN_speed;
00740       }
00741    }
00742    /*
00743     * on Freebsd, SETFRAGMENT does not work very well on some cards.
00744     * Default to use 256 bytes, let the user override
00745     */
00746    if (o->frags) {
00747       fmt = o->frags;
00748       res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt);
00749       if (res < 0) {
00750          if (!(o->warned & WARN_frag)) {
00751             ast_log(LOG_WARNING,
00752                "Unable to set fragment size -- sound may be choppy\n");
00753             o->warned |= WARN_frag;
00754          }
00755       }
00756    }
00757    /* on some cards, we need SNDCTL_DSP_SETTRIGGER to start outputting */
00758    res = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
00759    res = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &res);
00760    /* it may fail if we are in half duplex, never mind */
00761    return 0;
00762 }

static void* sound_thread ( void *  arg  )  [static]

Definition at line 594 of file chan_oss.c.

References ast_log(), ast_select(), chan_oss_pvt::cursound, errno, sound::ind, LOG_WARNING, MAX, O_CLOSE, chan_oss_pvt::owner, send_sound(), setformat(), chan_oss_pvt::sndcmd, chan_oss_pvt::sounddev, and sounds.

00595 {
00596    char ign[4096];
00597    struct chan_oss_pvt *o = (struct chan_oss_pvt *) arg;
00598 
00599    /*
00600     * Just in case, kick the driver by trying to read from it.
00601     * Ignore errors - this read is almost guaranteed to fail.
00602     */
00603    if (read(o->sounddev, ign, sizeof(ign)) < 0) {
00604    }
00605    for (;;) {
00606       fd_set rfds, wfds;
00607       int maxfd, res;
00608 
00609       FD_ZERO(&rfds);
00610       FD_ZERO(&wfds);
00611       FD_SET(o->sndcmd[0], &rfds);
00612       maxfd = o->sndcmd[0];   /* pipe from the main process */
00613       if (o->cursound > -1 && o->sounddev < 0)
00614          setformat(o, O_RDWR);   /* need the channel, try to reopen */
00615       else if (o->cursound == -1 && o->owner == NULL)
00616          setformat(o, O_CLOSE);  /* can close */
00617       if (o->sounddev > -1) {
00618          if (!o->owner) {  /* no one owns the audio, so we must drain it */
00619             FD_SET(o->sounddev, &rfds);
00620             maxfd = MAX(o->sounddev, maxfd);
00621          }
00622          if (o->cursound > -1) {
00623             FD_SET(o->sounddev, &wfds);
00624             maxfd = MAX(o->sounddev, maxfd);
00625          }
00626       }
00627       /* ast_select emulates linux behaviour in terms of timeout handling */
00628       res = ast_select(maxfd + 1, &rfds, &wfds, NULL, NULL);
00629       if (res < 1) {
00630          ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
00631          sleep(1);
00632          continue;
00633       }
00634       if (FD_ISSET(o->sndcmd[0], &rfds)) {
00635          /* read which sound to play from the pipe */
00636          int i, what = -1;
00637 
00638          if (read(o->sndcmd[0], &what, sizeof(what)) != sizeof(what)) {
00639             ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
00640             continue;
00641          }
00642          for (i = 0; sounds[i].ind != -1; i++) {
00643             if (sounds[i].ind == what) {
00644                o->cursound = i;
00645                o->sampsent = 0;
00646                o->nosound = 1;   /* block audio from pbx */
00647                break;
00648             }
00649          }
00650          if (sounds[i].ind == -1)
00651             ast_log(LOG_WARNING, "invalid sound index: %d\n", what);
00652       }
00653       if (o->sounddev > -1) {
00654          if (FD_ISSET(o->sounddev, &rfds))   /* read and ignore errors */
00655             if (read(o->sounddev, ign, sizeof(ign)) < 0) {
00656             }
00657          if (FD_ISSET(o->sounddev, &wfds))
00658             send_sound(o);
00659       }
00660    }
00661    return NULL;            /* Never reached */
00662 }

static int soundcard_writeframe ( struct chan_oss_pvt o,
short *  data 
) [static]

Definition at line 511 of file chan_oss.c.

References ast_log(), FRAME_SIZE, LOG_WARNING, chan_oss_pvt::queuesize, setformat(), chan_oss_pvt::sounddev, used_blocks(), and chan_oss_pvt::w_errors.

Referenced by oss_write(), and send_sound().

00512 {
00513    int res;
00514 
00515    if (o->sounddev < 0)
00516       setformat(o, O_RDWR);
00517    if (o->sounddev < 0)
00518       return 0;            /* not fatal */
00519    /*
00520     * Nothing complex to manage the audio device queue.
00521     * If the buffer is full just drop the extra, otherwise write.
00522     * XXX in some cases it might be useful to write anyways after
00523     * a number of failures, to restart the output chain.
00524     */
00525    res = used_blocks(o);
00526    if (res > o->queuesize) {  /* no room to write a block */
00527       if (o->w_errors++ == 0 && (oss_debug & 0x4))
00528          ast_log(LOG_WARNING, "write: used %d blocks (%d)\n", res, o->w_errors);
00529       return 0;
00530    }
00531    o->w_errors = 0;
00532    return write(o->sounddev, ((void *) data), FRAME_SIZE * 2);
00533 }

static void store_boost ( struct chan_oss_pvt o,
char *  s 
) [static]

Definition at line 1577 of file chan_oss.c.

References ast_log(), chan_oss_pvt::boost, BOOST_MAX, BOOST_SCALE, and LOG_WARNING.

Referenced by do_boost(), and store_config().

01578 {
01579    double boost = 0;
01580    if (sscanf(s, "%30lf", &boost) != 1) {
01581       ast_log(LOG_WARNING, "invalid boost <%s>\n", s);
01582       return;
01583    }
01584    if (boost < -BOOST_MAX) {
01585       ast_log(LOG_WARNING, "boost %s too small, using %d\n", s, -BOOST_MAX);
01586       boost = -BOOST_MAX;
01587    } else if (boost > BOOST_MAX) {
01588       ast_log(LOG_WARNING, "boost %s too large, using %d\n", s, BOOST_MAX);
01589       boost = BOOST_MAX;
01590    }
01591    boost = exp(log(10) * boost / 20) * BOOST_SCALE;
01592    o->boost = boost;
01593    ast_log(LOG_WARNING, "setting boost %s to %d\n", s, o->boost);
01594 }

static void store_callerid ( struct chan_oss_pvt o,
char *  s 
) [static]

Definition at line 1732 of file chan_oss.c.

References ast_callerid_split(), chan_oss_pvt::cid_name, and chan_oss_pvt::cid_num.

Referenced by store_config().

01733 {
01734    ast_callerid_split(s, o->cid_name, sizeof(o->cid_name), o->cid_num, sizeof(o->cid_num));
01735 }

static struct chan_oss_pvt* store_config ( struct ast_config cfg,
char *  ctg 
) [static]

Definition at line 1740 of file chan_oss.c.

References asprintf, ast_calloc, ast_copy_string(), ast_jb_read_conf(), ast_log(), ast_strdup, ast_strlen_zero(), ast_tvnow(), ast_variable_browse(), chan_oss_pvt::autoanswer, chan_oss_pvt::autohangup, chan_oss_pvt::ctx, DEV_DSP, chan_oss_pvt::device, errno, chan_oss_pvt::ext, chan_oss_pvt::frags, global_jbconf, chan_oss_pvt::language, chan_oss_pvt::lastopen, LOG_WARNING, M_BOOL, M_END, M_F, M_START, M_STR, M_UINT, chan_oss_pvt::mixer_cmd, chan_oss_pvt::mohinterpret, ast_variable::name, chan_oss_pvt::name, ast_variable::next, oss_active, oss_default, chan_oss_pvt::overridecontext, chan_oss_pvt::queuesize, store_boost(), store_callerid(), store_mixer(), and ast_variable::value.

Referenced by load_module().

01741 {
01742    struct ast_variable *v;
01743    struct chan_oss_pvt *o;
01744 
01745    if (ctg == NULL) {
01746       o = &oss_default;
01747       ctg = "general";
01748    } else {
01749       if (!(o = ast_calloc(1, sizeof(*o))))
01750          return NULL;
01751       *o = oss_default;
01752       /* "general" is also the default thing */
01753       if (strcmp(ctg, "general") == 0) {
01754          o->name = ast_strdup("dsp");
01755          oss_active = o->name;
01756          goto openit;
01757       }
01758       o->name = ast_strdup(ctg);
01759    }
01760 
01761    strcpy(o->mohinterpret, "default");
01762 
01763    o->lastopen = ast_tvnow(); /* don't leave it 0 or tvdiff may wrap */
01764    /* fill other fields from configuration */
01765    for (v = ast_variable_browse(cfg, ctg); v; v = v->next) {
01766       M_START(v->name, v->value);
01767 
01768       /* handle jb conf */
01769       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
01770          continue;
01771 
01772       M_BOOL("autoanswer", o->autoanswer)
01773          M_BOOL("autohangup", o->autohangup)
01774          M_BOOL("overridecontext", o->overridecontext)
01775          M_STR("device", o->device)
01776          M_UINT("frags", o->frags)
01777          M_UINT("debug", oss_debug)
01778          M_UINT("queuesize", o->queuesize)
01779          M_STR("context", o->ctx)
01780          M_STR("language", o->language)
01781          M_STR("mohinterpret", o->mohinterpret)
01782          M_STR("extension", o->ext)
01783          M_F("mixer", store_mixer(o, v->value))
01784          M_F("callerid", store_callerid(o, v->value))
01785          M_F("boost", store_boost(o, v->value))
01786          M_END(;
01787          );
01788    }
01789    if (ast_strlen_zero(o->device))
01790       ast_copy_string(o->device, DEV_DSP, sizeof(o->device));
01791    if (o->mixer_cmd) {
01792       char *cmd;
01793 
01794       if (asprintf(&cmd, "mixer %s", o->mixer_cmd) < 0) {
01795          ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
01796       } else {
01797          ast_log(LOG_WARNING, "running [%s]\n", cmd);
01798          if (system(cmd) < 0) {
01799             ast_log(LOG_WARNING, "system() failed: %s\n", strerror(errno));
01800          }
01801          free(cmd);
01802       }
01803    }
01804    if (o == &oss_default)     /* we are done with the default */
01805       return NULL;
01806 
01807   openit:
01808 #if TRYOPEN
01809    if (setformat(o, O_RDWR) < 0) {  /* open device */
01810       if (option_verbose > 0) {
01811          ast_verbose(VERBOSE_PREFIX_2 "Device %s not detected\n", ctg);
01812          ast_verbose(VERBOSE_PREFIX_2 "Turn off OSS support by adding " "'noload=chan_oss.so' in /etc/asterisk/modules.conf\n");
01813       }
01814       goto error;
01815    }
01816    if (o->duplex != M_FULL)
01817       ast_log(LOG_WARNING, "XXX I don't work right with non " "full-duplex sound cards XXX\n");
01818 #endif /* TRYOPEN */
01819    if (pipe(o->sndcmd) != 0) {
01820       ast_log(LOG_ERROR, "Unable to create pipe\n");
01821       goto error;
01822    }
01823    ast_pthread_create_background(&o->sthread, NULL, sound_thread, o);
01824    /* link into list of devices */
01825    if (o != &oss_default) {
01826       o->next = oss_default.next;
01827       oss_default.next = o;
01828    }
01829    return o;
01830 
01831   error:
01832    if (o != &oss_default)
01833       free(o);
01834    return NULL;
01835 }

static void store_mixer ( struct chan_oss_pvt o,
char *  s 
) [static]

Definition at line 1713 of file chan_oss.c.

References ast_log(), ast_strdup, free, LOG_WARNING, and chan_oss_pvt::mixer_cmd.

Referenced by store_config().

01714 {
01715    int i;
01716 
01717    for (i = 0; i < strlen(s); i++) {
01718       if (!isalnum(s[i]) && strchr(" \t-/", s[i]) == NULL) {
01719          ast_log(LOG_WARNING, "Suspect char %c in mixer cmd, ignoring:\n\t%s\n", s[i], s);
01720          return;
01721       }
01722    }
01723    if (o->mixer_cmd)
01724       free(o->mixer_cmd);
01725    o->mixer_cmd = ast_strdup(s);
01726    ast_log(LOG_WARNING, "setting mixer %s\n", s);
01727 }

static int unload_module ( void   )  [static]

Definition at line 1875 of file chan_oss.c.

References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, cli_oss, chan_oss_pvt::next, oss_default, oss_tech, chan_oss_pvt::owner, chan_oss_pvt::sndcmd, and chan_oss_pvt::sounddev.

01876 {
01877    struct chan_oss_pvt *o;
01878 
01879    ast_channel_unregister(&oss_tech);
01880    ast_cli_unregister_multiple(cli_oss, sizeof(cli_oss) / sizeof(struct ast_cli_entry));
01881 
01882    for (o = oss_default.next; o; o = o->next) {
01883       close(o->sounddev);
01884       if (o->sndcmd[0] > 0) {
01885          close(o->sndcmd[0]);
01886          close(o->sndcmd[1]);
01887       }
01888       if (o->owner)
01889          ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
01890       if (o->owner)
01891          return -1;
01892       /* XXX what about the thread ? */
01893       /* XXX what about the memory allocated ? */
01894    }
01895    return 0;
01896 }

static int used_blocks ( struct chan_oss_pvt o  )  [static]

Definition at line 489 of file chan_oss.c.

References ast_log(), LOG_WARNING, chan_oss_pvt::sounddev, chan_oss_pvt::total_blocks, WARN_used_blocks, and chan_oss_pvt::warned.

Referenced by soundcard_writeframe().

00490 {
00491    struct audio_buf_info info;
00492 
00493    if (ioctl(o->sounddev, SNDCTL_DSP_GETOSPACE, &info)) {
00494       if (!(o->warned & WARN_used_blocks)) {
00495          ast_log(LOG_WARNING, "Error reading output space\n");
00496          o->warned |= WARN_used_blocks;
00497       }
00498       return 1;
00499    }
00500 
00501    if (o->total_blocks == 0) {
00502       if (0)               /* debugging */
00503          ast_log(LOG_WARNING, "fragtotal %d size %d avail %d\n", info.fragstotal, info.fragsize, info.fragments);
00504       o->total_blocks = info.fragments;
00505    }
00506 
00507    return o->total_blocks - info.fragments;
00508 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "OSS Console Channel Driver" , .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 1898 of file chan_oss.c.

char active_usage[] [static]

Initial value:

   "Usage: console active [device]\n"
   "       If used without a parameter, displays which device is the current\n"
   "console.  If a device is specified, the console sound device is changed to\n"
   "the device specified.\n"

Definition at line 1568 of file chan_oss.c.

char answer_usage[] [static]

Initial value:

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

Definition at line 1180 of file chan_oss.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 1898 of file chan_oss.c.

char autoanswer_usage[] [static]

Initial value:

   "Usage: console 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 1127 of file chan_oss.c.

struct ast_cli_entry cli_oss[] [static]

Definition at line 1662 of file chan_oss.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_oss_active_deprecated [static]

Initial value:

 {
   { "console", NULL },
   console_active_deprecated, NULL,
        NULL }

Definition at line 1657 of file chan_oss.c.

struct ast_cli_entry cli_oss_answer_deprecated [static]

Initial value:

 {
   { "answer", NULL },
   console_answer_deprecated, NULL,
   NULL }

Definition at line 1607 of file chan_oss.c.

struct ast_cli_entry cli_oss_autoanswer_deprecated [static]

Initial value:

 {
   { "autoanswer", NULL },
   console_autoanswer_deprecated, NULL,
        NULL, autoanswer_complete_deprecated }

Definition at line 1647 of file chan_oss.c.

struct ast_cli_entry cli_oss_boost_deprecated [static]

Initial value:

 {
   { "oss", "boost", NULL },
   do_boost, NULL,
   NULL }

Definition at line 1652 of file chan_oss.c.

struct ast_cli_entry cli_oss_dial_deprecated [static]

Initial value:

 {
   { "dial", NULL },
   console_dial_deprecated, NULL,
        NULL }

Definition at line 1622 of file chan_oss.c.

struct ast_cli_entry cli_oss_flash_deprecated [static]

Initial value:

 {
   { "flash", NULL },
   console_flash_deprecated, NULL,
   NULL }

Definition at line 1617 of file chan_oss.c.

struct ast_cli_entry cli_oss_hangup_deprecated [static]

Initial value:

 {
   { "hangup", NULL },
   console_hangup_deprecated, NULL,
   NULL }

Definition at line 1612 of file chan_oss.c.

struct ast_cli_entry cli_oss_mute_deprecated [static]

Initial value:

 {
   { "mute", NULL },
   console_mute_deprecated, NULL,
        NULL }

Definition at line 1627 of file chan_oss.c.

struct ast_cli_entry cli_oss_send_text_deprecated [static]

Initial value:

 {
   { "send", "text", NULL },
   console_sendtext_deprecated, NULL,
        NULL }

Definition at line 1642 of file chan_oss.c.

struct ast_cli_entry cli_oss_transfer_deprecated [static]

Initial value:

 {
   { "transfer", NULL },
   console_transfer_deprecated, NULL,
        NULL }

Definition at line 1637 of file chan_oss.c.

struct ast_cli_entry cli_oss_unmute_deprecated [static]

Initial value:

 {
   { "unmute", NULL },
   console_unmute_deprecated, NULL,
        NULL }

Definition at line 1632 of file chan_oss.c.

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

Definition at line 284 of file chan_oss.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled

Definition at line 86 of file chan_oss.c.

char dial_usage[] [static]

Initial value:

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

Definition at line 1408 of file chan_oss.c.

char flash_usage[] [static]

Initial value:

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

Definition at line 1322 of file chan_oss.c.

struct ast_jb_conf global_jbconf [static]

Definition at line 93 of file chan_oss.c.

char hangup_usage[] [static]

Initial value:

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

Definition at line 1280 of file chan_oss.c.

char mute_usage[] [static]

Initial value:

   "Usage: console mute\nMutes the microphone\n"

Definition at line 1436 of file chan_oss.c.

char* oss_active [static]

Definition at line 400 of file chan_oss.c.

Referenced by __console_mute_unmute(), console_active(), console_active_deprecated(), console_answer(), console_answer_deprecated(), console_autoanswer(), console_autoanswer_deprecated(), console_dial(), console_dial_deprecated(), console_flash(), console_flash_deprecated(), console_hangup(), console_hangup_deprecated(), console_sendtext(), console_sendtext_deprecated(), console_transfer(), console_transfer_deprecated(), do_boost(), load_module(), and store_config().

int oss_debug [static]

Definition at line 286 of file chan_oss.c.

struct chan_oss_pvt oss_default [static]

Definition at line 385 of file chan_oss.c.

Referenced by console_active(), console_active_deprecated(), find_desc(), store_config(), and unload_module().

struct ast_channel_tech oss_tech [static]

Definition at line 417 of file chan_oss.c.

Referenced by load_module(), oss_new(), oss_read(), and unload_module().

char sendtext_usage[] [static]

Initial value:

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

Definition at line 1238 of file chan_oss.c.

struct sound sounds[] [static]

Definition at line 303 of file chan_oss.c.

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

Definition at line 415 of file chan_oss.c.

char transfer_usage[] [static]

Initial value:

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

Definition at line 1519 of file chan_oss.c.

char unmute_usage[] [static]

Initial value:

   "Usage: console unmute\nUnmutes the microphone\n"

Definition at line 1455 of file chan_oss.c.


Generated on Tue Apr 6 15:45:48 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7