Sat Aug 6 00:39:47 2011

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 <signal.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 361 of file chan_oss.c.

Referenced by store_boost().

#define BOOST_SCALE   (1<<9)

Definition at line 360 of file chan_oss.c.

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

#define DEV_DSP   "/dev/dsp"

Definition at line 275 of file chan_oss.c.

Referenced by store_config().

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

Definition at line 258 of file chan_oss.c.

#define FRAME_SIZE   160

Definition at line 252 of file chan_oss.c.

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

Definition at line 218 of file chan_oss.c.

Referenced by store_config().

#define M_END (  )     x;

Definition at line 216 of file chan_oss.c.

Referenced by store_config().

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

Definition at line 217 of file chan_oss.c.

Referenced by store_config().

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

Definition at line 214 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 220 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 219 of file chan_oss.c.

Referenced by store_config().

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

Definition at line 282 of file chan_oss.c.

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

Definition at line 279 of file chan_oss.c.

#define O_CLOSE   0x444

Definition at line 270 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 253 of file chan_oss.c.

#define TEXT_SIZE   256

Definition at line 265 of file chan_oss.c.

Referenced by console_sendtext(), and console_sendtext_deprecated().

#define WARN_frag   4

Definition at line 350 of file chan_oss.c.

Referenced by setformat().

#define WARN_speed   2

Definition at line 349 of file chan_oss.c.

Referenced by setformat().

#define WARN_used_blocks   1

Definition at line 348 of file chan_oss.c.

Referenced by used_blocks().


Function Documentation

static int __console_mute_unmute ( int  mute  )  [static]

Definition at line 1413 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().

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

static void __reg_module ( void   )  [static]

Definition at line 1913 of file chan_oss.c.

static void __unreg_module ( void   )  [static]

Definition at line 1913 of file chan_oss.c.

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

Definition at line 462 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().

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

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

Definition at line 1121 of file chan_oss.c.

References ast_cli_complete().

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

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

Definition at line 1114 of file chan_oss.c.

References ast_cli_complete().

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

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

Definition at line 1547 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.

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

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

Definition at line 1525 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.

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

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

Definition at line 1159 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().

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

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

Definition at line 1137 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().

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

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

Definition at line 1090 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.

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

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

Definition at line 1067 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.

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

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

Definition at line 1368 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.

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

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

Definition at line 1327 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.

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

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

Definition at line 1304 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.

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

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

Definition at line 1285 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.

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

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

Definition at line 1262 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().

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

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

Definition at line 1243 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().

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

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

Definition at line 1429 of file chan_oss.c.

References __console_mute_unmute(), and RESULT_SHOWUSAGE.

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

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

Definition at line 1421 of file chan_oss.c.

References __console_mute_unmute(), and RESULT_SHOWUSAGE.

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

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

Definition at line 1214 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.

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

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

Definition at line 1189 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.

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

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

Definition at line 1490 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.

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

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

Definition at line 1459 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.

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

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

Definition at line 1448 of file chan_oss.c.

References __console_mute_unmute(), and RESULT_SHOWUSAGE.

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

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

Definition at line 1440 of file chan_oss.c.

References __console_mute_unmute(), and RESULT_SHOWUSAGE.

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

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

Definition at line 1597 of file chan_oss.c.

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

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

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

Definition at line 438 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().

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

static int load_module ( void   )  [static]

Definition at line 1838 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().

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

static int oss_answer ( struct ast_channel c  )  [static]

Definition at line 825 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.

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

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

Definition at line 800 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.

00801 {
00802    struct chan_oss_pvt *o = c->tech_pvt;
00803    struct ast_frame f = { 0, };
00804 
00805    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);
00806    if (o->autoanswer) {
00807       ast_verbose(" << Auto-answered >> \n");
00808       f.frametype = AST_FRAME_CONTROL;
00809       f.subclass = AST_CONTROL_ANSWER;
00810       ast_queue_frame(c, &f);
00811       o->hookstate = 1;
00812    } else {
00813       ast_verbose("<< Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
00814       f.frametype = AST_FRAME_CONTROL;
00815       f.subclass = AST_CONTROL_RINGING;
00816       ast_queue_frame(c, &f);
00817       ring(o, AST_CONTROL_RING);
00818    }
00819    return 0;
00820 }

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

Definition at line 768 of file chan_oss.c.

00769 {
00770    return 0;
00771 }

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

Definition at line 773 of file chan_oss.c.

References ast_verbose().

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

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

Definition at line 950 of file chan_oss.c.

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

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

static int oss_hangup ( struct ast_channel c  )  [static]

Definition at line 841 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.

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

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

Definition at line 957 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.

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

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

Definition at line 1001 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().

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

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

Definition at line 901 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.

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

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

Definition at line 1039 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.

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

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

Definition at line 781 of file chan_oss.c.

References ast_verbose().

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

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

Definition at line 865 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.

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

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

Definition at line 789 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().

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

static void send_sound ( struct chan_oss_pvt o  )  [static]

Definition at line 546 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.

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

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

Definition at line 670 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, 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().

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

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

Definition at line 595 of file chan_oss.c.

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

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

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

Definition at line 512 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().

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

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

Definition at line 1578 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().

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

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

Definition at line 1733 of file chan_oss.c.

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

Referenced by store_config().

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

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

Definition at line 1741 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().

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

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

Definition at line 1714 of file chan_oss.c.

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

Referenced by store_config().

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

static int unload_module ( void   )  [static]

Definition at line 1876 of file chan_oss.c.

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

01877 {
01878    struct chan_oss_pvt *o, *next;
01879 
01880    ast_channel_unregister(&oss_tech);
01881    ast_cli_unregister_multiple(cli_oss, sizeof(cli_oss) / sizeof(struct ast_cli_entry));
01882 
01883    o = oss_default.next;
01884    while (o) {
01885       if (o->owner) {
01886          ast_softhangup(o->owner, AST_SOFTHANGUP_APPUNLOAD);
01887          /* Give the channel a chance to go away */
01888          sched_yield();
01889       }
01890       if (o->owner) {
01891          return -1;
01892       }
01893       oss_default.next = o->next;
01894       if (o->sthread > 0) {
01895          pthread_cancel(o->sthread);
01896          pthread_kill(o->sthread, SIGURG);
01897          pthread_join(o->sthread, NULL);
01898       }
01899       close(o->sounddev);
01900       if (o->sndcmd[0] > 0) {
01901          close(o->sndcmd[0]);
01902          close(o->sndcmd[1]);
01903       }
01904       next = o->next;
01905       if (o->sthread > 0) {
01906          ast_free(o);
01907       }
01908       o = next;
01909    }
01910    return 0;
01911 }

static int used_blocks ( struct chan_oss_pvt o  )  [static]

Definition at line 490 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().

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


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 1913 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 1569 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 1181 of file chan_oss.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 1913 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 1128 of file chan_oss.c.

struct ast_cli_entry cli_oss[] [static]

Definition at line 1663 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 1658 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 1608 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 1648 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 1653 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 1623 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 1618 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 1613 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 1628 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 1643 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 1638 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 1633 of file chan_oss.c.

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

Definition at line 285 of file chan_oss.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled

Definition at line 87 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 1409 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 1323 of file chan_oss.c.

struct ast_jb_conf global_jbconf [static]

Definition at line 94 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 1281 of file chan_oss.c.

char mute_usage[] [static]

Initial value:

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

Definition at line 1437 of file chan_oss.c.

char* oss_active [static]

Definition at line 401 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 287 of file chan_oss.c.

struct chan_oss_pvt oss_default [static]

Definition at line 386 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 418 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 1239 of file chan_oss.c.

struct sound sounds[] [static]

Definition at line 304 of file chan_oss.c.

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

Definition at line 416 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 1520 of file chan_oss.c.

char unmute_usage[] [static]

Initial value:

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

Definition at line 1456 of file chan_oss.c.


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