2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2005, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * FreeBSD changes and multiple device support by Luigi Rizzo, 2005.05.25
9 * note-this code best seen with ts=8 (8-spaces tabs) in the editor
11 * See http://www.asterisk.org for more information about
12 * the Asterisk project. Please do not directly contact
13 * any of the maintainers of this project for assistance;
14 * the project provides a web site, mailing lists and IRC
15 * channels for your use.
17 * This program is free software, distributed under the terms of
18 * the GNU General Public License Version 2. See the LICENSE file
19 * at the top of the source tree.
24 * \brief Channel driver for OSS sound cards
26 * \author Mark Spencer <markster@digium.com>
30 * \arg \ref Config_oss
32 * \ingroup channel_drivers
36 <depend>ossaudio</depend>
41 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
48 #include <sys/ioctl.h>
55 #include <linux/soundcard.h>
56 #elif defined(__FreeBSD__)
57 #include <sys/soundcard.h>
59 #include <soundcard.h>
62 #include "asterisk/lock.h"
63 #include "asterisk/frame.h"
64 #include "asterisk/logger.h"
65 #include "asterisk/callerid.h"
66 #include "asterisk/channel.h"
67 #include "asterisk/module.h"
68 #include "asterisk/options.h"
69 #include "asterisk/pbx.h"
70 #include "asterisk/config.h"
71 #include "asterisk/cli.h"
72 #include "asterisk/utils.h"
73 #include "asterisk/causes.h"
74 #include "asterisk/endian.h"
75 #include "asterisk/stringfields.h"
76 #include "asterisk/abstract_jb.h"
77 #include "asterisk/musiconhold.h"
79 /* ringtones we use */
85 /*! Global jitterbuffer configuration - by default, jb is disabled */
86 static struct ast_jb_conf default_jbconf
=
90 .resync_threshold
= -1,
93 static struct ast_jb_conf global_jbconf
;
96 * Basic mode of operation:
98 * we have one keyboard (which receives commands from the keyboard)
99 * and multiple headset's connected to audio cards.
100 * Cards/Headsets are named as the sections of oss.conf.
101 * The section called [general] contains the default parameters.
103 * At any time, the keyboard is attached to one card, and you
104 * can switch among them using the command 'console foo'
105 * where 'foo' is the name of the card you want.
107 * oss.conf parameters are
111 ; General config options, with default values shown.
112 ; You should use one section per device, with [general] being used
113 ; for the first device and also as a template for other devices.
115 ; All but 'debug' can go also in the device-specific sections.
117 ; debug = 0x0 ; misc debug flags, default is 0
119 ; Set the device to use for I/O
122 ; Optional mixer command to run upon startup (e.g. to set
123 ; volume levels, mutes, etc.
126 ; Software mic volume booster (or attenuator), useful for sound
127 ; cards or microphones with poor sensitivity. The volume level
128 ; is in dB, ranging from -20.0 to +20.0
129 ; boost = n ; mic volume boost in dB
131 ; Set the callerid for outgoing calls
132 ; callerid = John Doe <555-1234>
134 ; autoanswer = no ; no autoanswer on call
135 ; autohangup = yes ; hangup when other party closes
136 ; extension = s ; default extension to call
137 ; context = default ; default context for outgoing calls
138 ; language = "" ; default language
140 ; Default Music on Hold class to use when this channel is placed on hold in
141 ; the case that the music class is not set on the channel with
142 ; Set(CHANNEL(musicclass)=whatever) in the dialplan and the peer channel
143 ; putting this one on hold did not suggest a class to use.
145 ; mohinterpret=default
147 ; If you set overridecontext to 'yes', then the whole dial string
148 ; will be interpreted as an extension, which is extremely useful
149 ; to dial SIP, IAX and other extensions which use the '@' character.
150 ; The default is 'no' just for backward compatibility, but the
151 ; suggestion is to change it.
152 ; overridecontext = no ; if 'no', the last @ will start the context
153 ; if 'yes' the whole string is an extension.
155 ; low level device parameters in case you have problems with the
156 ; device driver on your operating system. You should not touch these
157 ; unless you know what you are doing.
158 ; queuesize = 10 ; frames in device driver
159 ; frags = 8 ; argument to SETFRAGMENT
161 ;------------------------------ JITTER BUFFER CONFIGURATION --------------------------
162 ; jbenable = yes ; Enables the use of a jitterbuffer on the receiving side of an
163 ; OSS channel. Defaults to "no". An enabled jitterbuffer will
164 ; be used only if the sending side can create and the receiving
165 ; side can not accept jitter. The OSS channel can't accept jitter,
166 ; thus an enabled jitterbuffer on the receive OSS side will always
167 ; be used if the sending side can create jitter.
169 ; jbmaxsize = 200 ; Max length of the jitterbuffer in milliseconds.
171 ; jbresyncthreshold = 1000 ; Jump in the frame timestamps over which the jitterbuffer is
172 ; resynchronized. Useful to improve the quality of the voice, with
173 ; big jumps in/broken timestamps, usualy sent from exotic devices
174 ; and programs. Defaults to 1000.
176 ; jbimpl = fixed ; Jitterbuffer implementation, used on the receiving side of an OSS
177 ; channel. Two implementations are currenlty available - "fixed"
178 ; (with size always equals to jbmax-size) and "adaptive" (with
179 ; variable size, actually the new jb of IAX2). Defaults to fixed.
181 ; jblog = no ; Enables jitterbuffer frame logging. Defaults to "no".
182 ;-----------------------------------------------------------------------------------
185 ; device = /dev/dsp1 ; alternate device
189 .. and so on for the other cards.
194 * Helper macros to parse config arguments. They will go in a common
195 * header file if their usage is globally accepted. In the meantime,
196 * we define them here. Typical usage is as below.
197 * Remember to open a block right before M_START (as it declares
198 * some variables) and use the M_* macros WITHOUT A SEMICOLON:
201 * M_START(v->name, v->value)
203 * M_BOOL("dothis", x->flag1)
204 * M_STR("name", x->somestring)
205 * M_F("bar", some_c_code)
206 * M_END(some_final_statement)
207 * ... other code in the block
210 * XXX NOTE these macros should NOT be replicated in other parts of asterisk.
211 * Likely we will come up with a better way of doing config file parsing.
213 #define M_START(var, val) \
214 char *__s = var; char *__val = val;
216 #define M_F(tag, f) if (!strcasecmp((__s), tag)) { f; } else
217 #define M_BOOL(tag, dst) M_F(tag, (dst) = ast_true(__val) )
218 #define M_UINT(tag, dst) M_F(tag, (dst) = strtoul(__val, NULL, 0) )
219 #define M_STR(tag, dst) M_F(tag, ast_copy_string(dst, __val, sizeof(dst)))
222 * The following parameters are used in the driver:
224 * FRAME_SIZE the size of an audio frame, in samples.
225 * 160 is used almost universally, so you should not change it.
227 * FRAGS the argument for the SETFRAGMENT ioctl.
228 * Overridden by the 'frags' parameter in oss.conf
230 * Bits 0-7 are the base-2 log of the device's block size,
231 * bits 16-31 are the number of blocks in the driver's queue.
232 * There are a lot of differences in the way this parameter
233 * is supported by different drivers, so you may need to
234 * experiment a bit with the value.
235 * A good default for linux is 30 blocks of 64 bytes, which
236 * results in 6 frames of 320 bytes (160 samples).
237 * FreeBSD works decently with blocks of 256 or 512 bytes,
238 * leaving the number unspecified.
239 * Note that this only refers to the device buffer size,
240 * this module will then try to keep the lenght of audio
241 * buffered within small constraints.
243 * QUEUE_SIZE The max number of blocks actually allowed in the device
244 * driver's buffer, irrespective of the available number.
245 * Overridden by the 'queuesize' parameter in oss.conf
247 * Should be >=2, and at most as large as the hw queue above
248 * (otherwise it will never be full).
251 #define FRAME_SIZE 160
252 #define QUEUE_SIZE 10
254 #if defined(__FreeBSD__)
257 #define FRAGS ( ( (6 * 5) << 16 ) | 0x6 )
261 * XXX text message sizes are probably 256 chars, but i am
262 * not sure if there is a suitable definition anywhere.
264 #define TEXT_SIZE 256
267 #define TRYOPEN 1 /* try to open on startup */
269 #define O_CLOSE 0x444 /* special 'close' mode for device */
270 /* Which device to use */
271 #if defined( __OpenBSD__ ) || defined( __NetBSD__ )
272 #define DEV_DSP "/dev/audio"
274 #define DEV_DSP "/dev/dsp"
278 #define MIN(a,b) ((a) < (b) ? (a) : (b))
281 #define MAX(a,b) ((a) > (b) ? (a) : (b))
284 static char *config
= "oss.conf"; /* default config file */
286 static int oss_debug
;
289 * Each sound is made of 'datalen' samples of sound, repeated as needed to
290 * generate 'samplen' samples of data, then followed by 'silencelen' samples
291 * of silence. The loop is repeated if 'repeat' is set.
303 static struct sound sounds
[] = {
304 { AST_CONTROL_RINGING
, "RINGING", ringtone
, sizeof(ringtone
)/2, 16000, 32000, 1 },
305 { AST_CONTROL_BUSY
, "BUSY", busy
, sizeof(busy
)/2, 4000, 4000, 1 },
306 { AST_CONTROL_CONGESTION
, "CONGESTION", busy
, sizeof(busy
)/2, 2000, 2000, 1 },
307 { AST_CONTROL_RING
, "RING10", ring10
, sizeof(ring10
)/2, 16000, 32000, 1 },
308 { AST_CONTROL_ANSWER
, "ANSWER", answer
, sizeof(answer
)/2, 2200, 0, 0 },
309 { -1, NULL
, 0, 0, 0, 0 }, /* end marker */
314 * descriptor for one of our channels.
315 * There is one used for 'default' values (from the [general] entry in
316 * the configuration file), and then one instance for each device
317 * (the default is cloned from [general], others are only created
318 * if the relevant section exists).
320 struct chan_oss_pvt
{
321 struct chan_oss_pvt
*next
;
325 * cursound indicates which in struct sound we play. -1 means nothing,
326 * any other value is a valid sound, in which case sampsent indicates
327 * the next sample to send in [0..samplen + silencelen]
328 * nosound is set to disable the audio data from the channel
329 * (so we can play the tones etc.).
331 int sndcmd
[2]; /* Sound command pipe */
332 int cursound
; /* index of sound to send */
333 int sampsent
; /* # of sound samples sent */
334 int nosound
; /* set to block audio from the PBX */
336 int total_blocks
; /* total blocks in the output device */
338 enum { M_UNSET
, M_FULL
, M_READ
, M_WRITE
} duplex
;
342 char *mixer_cmd
; /* initial command to issue to the mixer */
343 unsigned int queuesize
; /* max fragments in queue */
344 unsigned int frags
; /* parameter for SETFRAGMENT */
346 int warned
; /* various flags used for warnings */
347 #define WARN_used_blocks 1
350 int w_errors
; /* overfull in the write path */
351 struct timeval lastopen
;
356 /* boost support. BOOST_SCALE * 10 ^(BOOST_MAX/20) must
357 * be representable in 16 bits to avoid overflows.
359 #define BOOST_SCALE (1<<9)
360 #define BOOST_MAX 40 /* slightly less than 7 bits */
361 int boost
; /* input boost, scaled by BOOST_SCALE */
362 char device
[64]; /* device to open */
366 struct ast_channel
*owner
;
367 char ext
[AST_MAX_EXTENSION
];
368 char ctx
[AST_MAX_CONTEXT
];
369 char language
[MAX_LANGUAGE
];
370 char cid_name
[256]; /*XXX */
371 char cid_num
[256]; /*XXX */
372 char mohinterpret
[MAX_MUSICCLASS
];
374 /* buffers used in oss_write */
375 char oss_write_buf
[FRAME_SIZE
* 2];
377 /* buffers used in oss_read - AST_FRIENDLY_OFFSET space for headers
378 * plus enough room for a full frame
380 char oss_read_buf
[FRAME_SIZE
* 2 + AST_FRIENDLY_OFFSET
];
381 int readpos
; /* read position above */
382 struct ast_frame read_f
; /* returned by oss_read */
385 static struct chan_oss_pvt oss_default
= {
388 .duplex
= M_UNSET
, /* XXX check this */
391 .queuesize
= QUEUE_SIZE
,
395 .readpos
= AST_FRIENDLY_OFFSET
, /* start here on reads */
396 .lastopen
= { 0, 0 },
397 .boost
= BOOST_SCALE
,
400 static char *oss_active
; /* the active device */
402 static int setformat(struct chan_oss_pvt
*o
, int mode
);
404 static struct ast_channel
*oss_request(const char *type
, int format
, void *data
406 static int oss_digit_begin(struct ast_channel
*c
, char digit
);
407 static int oss_digit_end(struct ast_channel
*c
, char digit
, unsigned int duration
);
408 static int oss_text(struct ast_channel
*c
, const char *text
);
409 static int oss_hangup(struct ast_channel
*c
);
410 static int oss_answer(struct ast_channel
*c
);
411 static struct ast_frame
*oss_read(struct ast_channel
*chan
);
412 static int oss_call(struct ast_channel
*c
, char *dest
, int timeout
);
413 static int oss_write(struct ast_channel
*chan
, struct ast_frame
*f
);
414 static int oss_indicate(struct ast_channel
*chan
, int cond
, const void *data
, size_t datalen
);
415 static int oss_fixup(struct ast_channel
*oldchan
, struct ast_channel
*newchan
);
416 static char tdesc
[] = "OSS Console Channel Driver";
418 static const struct ast_channel_tech oss_tech
= {
420 .description
= tdesc
,
421 .capabilities
= AST_FORMAT_SLINEAR
,
422 .requester
= oss_request
,
423 .send_digit_begin
= oss_digit_begin
,
424 .send_digit_end
= oss_digit_end
,
425 .send_text
= oss_text
,
426 .hangup
= oss_hangup
,
427 .answer
= oss_answer
,
431 .indicate
= oss_indicate
,
436 * returns a pointer to the descriptor with the given name
438 static struct chan_oss_pvt
*find_desc(char *dev
)
440 struct chan_oss_pvt
*o
= NULL
;
443 ast_log(LOG_WARNING
, "null dev\n");
445 for (o
= oss_default
.next
; o
&& o
->name
&& dev
&& strcmp(o
->name
, dev
) != 0; o
= o
->next
);
448 ast_log(LOG_WARNING
, "could not find <%s>\n", dev
? dev
: "--no-device--");
454 * split a string in extension-context, returns pointers to malloc'ed
456 * If we do not have 'overridecontext' then the last @ is considered as
457 * a context separator, and the context is overridden.
458 * This is usually not very necessary as you can play with the dialplan,
459 * and it is nice not to need it because you have '@' in SIP addresses.
460 * Return value is the buffer address.
462 static char *ast_ext_ctx(const char *src
, char **ext
, char **ctx
)
464 struct chan_oss_pvt
*o
= find_desc(oss_active
);
466 if (ext
== NULL
|| ctx
== NULL
)
467 return NULL
; /* error */
471 if (src
&& *src
!= '\0')
472 *ext
= ast_strdup(src
);
477 if (!o
->overridecontext
) {
478 /* parse from the right */
479 *ctx
= strrchr(*ext
, '@');
488 * Returns the number of blocks used in the audio output channel
490 static int used_blocks(struct chan_oss_pvt
*o
)
492 struct audio_buf_info info
;
494 if (ioctl(o
->sounddev
, SNDCTL_DSP_GETOSPACE
, &info
)) {
495 if (!(o
->warned
& WARN_used_blocks
)) {
496 ast_log(LOG_WARNING
, "Error reading output space\n");
497 o
->warned
|= WARN_used_blocks
;
502 if (o
->total_blocks
== 0) {
503 if (0) /* debugging */
504 ast_log(LOG_WARNING
, "fragtotal %d size %d avail %d\n", info
.fragstotal
, info
.fragsize
, info
.fragments
);
505 o
->total_blocks
= info
.fragments
;
508 return o
->total_blocks
- info
.fragments
;
511 /* Write an exactly FRAME_SIZE sized frame */
512 static int soundcard_writeframe(struct chan_oss_pvt
*o
, short *data
)
517 setformat(o
, O_RDWR
);
519 return 0; /* not fatal */
521 * Nothing complex to manage the audio device queue.
522 * If the buffer is full just drop the extra, otherwise write.
523 * XXX in some cases it might be useful to write anyways after
524 * a number of failures, to restart the output chain.
526 res
= used_blocks(o
);
527 if (res
> o
->queuesize
) { /* no room to write a block */
528 if (o
->w_errors
++ == 0 && (oss_debug
& 0x4))
529 ast_log(LOG_WARNING
, "write: used %d blocks (%d)\n", res
, o
->w_errors
);
533 return write(o
->sounddev
, ((void *) data
), FRAME_SIZE
* 2);
537 * Handler for 'sound writable' events from the sound thread.
538 * Builds a frame from the high level description of the sounds,
539 * and passes it to the audio device.
540 * The actual sound is made of 1 or more sequences of sound samples
541 * (s->datalen, repeated to make s->samplen samples) followed by
542 * s->silencelen samples of silence. The position in the sequence is stored
543 * in o->sampsent, which goes between 0 .. s->samplen+s->silencelen.
544 * In case we fail to write a frame, don't update o->sampsent.
546 static void send_sound(struct chan_oss_pvt
*o
)
548 short myframe
[FRAME_SIZE
];
550 int l_sampsent
= o
->sampsent
;
553 if (o
->cursound
< 0) /* no sound to send */
556 s
= &sounds
[o
->cursound
];
558 for (ofs
= 0; ofs
< FRAME_SIZE
; ofs
+= l
) {
559 l
= s
->samplen
- l_sampsent
; /* # of available samples */
561 start
= l_sampsent
% s
->datalen
; /* source offset */
562 if (l
> FRAME_SIZE
- ofs
) /* don't overflow the frame */
563 l
= FRAME_SIZE
- ofs
;
564 if (l
> s
->datalen
- start
) /* don't overflow the source */
565 l
= s
->datalen
- start
;
566 bcopy(s
->data
+ start
, myframe
+ ofs
, l
* 2);
568 ast_log(LOG_WARNING
, "send_sound sound %d/%d of %d into %d\n", l_sampsent
, l
, s
->samplen
, ofs
);
570 } else { /* end of samples, maybe some silence */
571 static const short silence
[FRAME_SIZE
] = { 0, };
575 if (l
> FRAME_SIZE
- ofs
)
576 l
= FRAME_SIZE
- ofs
;
577 bcopy(silence
, myframe
+ ofs
, l
* 2);
579 } else { /* silence is over, restart sound if loop */
580 if (s
->repeat
== 0) { /* last block */
582 o
->nosound
= 0; /* allow audio data */
583 if (ofs
< FRAME_SIZE
) /* pad with silence */
584 bcopy(silence
, myframe
+ ofs
, (FRAME_SIZE
- ofs
) * 2);
590 l
= soundcard_writeframe(o
, myframe
);
592 o
->sampsent
= l_sampsent
; /* update status */
595 static void *sound_thread(void *arg
)
598 struct chan_oss_pvt
*o
= (struct chan_oss_pvt
*) arg
;
601 * Just in case, kick the driver by trying to read from it.
602 * Ignore errors - this read is almost guaranteed to fail.
604 read(o
->sounddev
, ign
, sizeof(ign
));
611 FD_SET(o
->sndcmd
[0], &rfds
);
612 maxfd
= o
->sndcmd
[0]; /* pipe from the main process */
613 if (o
->cursound
> -1 && o
->sounddev
< 0)
614 setformat(o
, O_RDWR
); /* need the channel, try to reopen */
615 else if (o
->cursound
== -1 && o
->owner
== NULL
)
616 setformat(o
, O_CLOSE
); /* can close */
617 if (o
->sounddev
> -1) {
618 if (!o
->owner
) { /* no one owns the audio, so we must drain it */
619 FD_SET(o
->sounddev
, &rfds
);
620 maxfd
= MAX(o
->sounddev
, maxfd
);
622 if (o
->cursound
> -1) {
623 FD_SET(o
->sounddev
, &wfds
);
624 maxfd
= MAX(o
->sounddev
, maxfd
);
627 /* ast_select emulates linux behaviour in terms of timeout handling */
628 res
= ast_select(maxfd
+ 1, &rfds
, &wfds
, NULL
, NULL
);
630 ast_log(LOG_WARNING
, "select failed: %s\n", strerror(errno
));
634 if (FD_ISSET(o
->sndcmd
[0], &rfds
)) {
635 /* read which sound to play from the pipe */
638 read(o
->sndcmd
[0], &what
, sizeof(what
));
639 for (i
= 0; sounds
[i
].ind
!= -1; i
++) {
640 if (sounds
[i
].ind
== what
) {
643 o
->nosound
= 1; /* block audio from pbx */
647 if (sounds
[i
].ind
== -1)
648 ast_log(LOG_WARNING
, "invalid sound index: %d\n", what
);
650 if (o
->sounddev
> -1) {
651 if (FD_ISSET(o
->sounddev
, &rfds
)) /* read and ignore errors */
652 read(o
->sounddev
, ign
, sizeof(ign
));
653 if (FD_ISSET(o
->sounddev
, &wfds
))
657 return NULL
; /* Never reached */
661 * reset and close the device if opened,
662 * then open and initialize it in the desired mode,
663 * trigger reads and writes so we can start using it.
665 static int setformat(struct chan_oss_pvt
*o
, int mode
)
667 int fmt
, desired
, res
, fd
;
669 if (o
->sounddev
>= 0) {
670 ioctl(o
->sounddev
, SNDCTL_DSP_RESET
, 0);
675 if (mode
== O_CLOSE
) /* we are done */
677 if (ast_tvdiff_ms(ast_tvnow(), o
->lastopen
) < 1000)
678 return -1; /* don't open too often */
679 o
->lastopen
= ast_tvnow();
680 fd
= o
->sounddev
= open(o
->device
, mode
| O_NONBLOCK
);
682 ast_log(LOG_WARNING
, "Unable to re-open DSP device %s: %s\n", o
->device
, strerror(errno
));
686 o
->owner
->fds
[0] = fd
;
688 #if __BYTE_ORDER == __LITTLE_ENDIAN
693 res
= ioctl(fd
, SNDCTL_DSP_SETFMT
, &fmt
);
695 ast_log(LOG_WARNING
, "Unable to set format to 16-bit signed\n");
700 res
= ioctl(fd
, SNDCTL_DSP_SETDUPLEX
, 0);
701 /* Check to see if duplex set (FreeBSD Bug) */
702 res
= ioctl(fd
, SNDCTL_DSP_GETCAPS
, &fmt
);
703 if (res
== 0 && (fmt
& DSP_CAP_DUPLEX
)) {
704 if (option_verbose
> 1)
705 ast_verbose(VERBOSE_PREFIX_2
"Console is full duplex\n");
718 res
= ioctl(fd
, SNDCTL_DSP_STEREO
, &fmt
);
720 ast_log(LOG_WARNING
, "Failed to set audio device to mono\n");
723 fmt
= desired
= DEFAULT_SAMPLE_RATE
; /* 8000 Hz desired */
724 res
= ioctl(fd
, SNDCTL_DSP_SPEED
, &fmt
);
727 ast_log(LOG_WARNING
, "Failed to set audio device to mono\n");
730 if (fmt
!= desired
) {
731 if (!(o
->warned
& WARN_speed
)) {
733 "Requested %d Hz, got %d Hz -- sound may be choppy\n",
735 o
->warned
|= WARN_speed
;
739 * on Freebsd, SETFRAGMENT does not work very well on some cards.
740 * Default to use 256 bytes, let the user override
744 res
= ioctl(fd
, SNDCTL_DSP_SETFRAGMENT
, &fmt
);
746 if (!(o
->warned
& WARN_frag
)) {
748 "Unable to set fragment size -- sound may be choppy\n");
749 o
->warned
|= WARN_frag
;
753 /* on some cards, we need SNDCTL_DSP_SETTRIGGER to start outputting */
754 res
= PCM_ENABLE_INPUT
| PCM_ENABLE_OUTPUT
;
755 res
= ioctl(fd
, SNDCTL_DSP_SETTRIGGER
, &res
);
756 /* it may fail if we are in half duplex, never mind */
761 * some of the standard methods supported by channels.
763 static int oss_digit_begin(struct ast_channel
*c
, char digit
)
768 static int oss_digit_end(struct ast_channel
*c
, char digit
, unsigned int duration
)
770 /* no better use for received digits than print them */
771 ast_verbose(" << Console Received digit %c of duration %u ms >> \n",
776 static int oss_text(struct ast_channel
*c
, const char *text
)
778 /* print received messages */
779 ast_verbose(" << Console Received text %s >> \n", text
);
783 /* Play ringtone 'x' on device 'o' */
784 static void ring(struct chan_oss_pvt
*o
, int x
)
786 write(o
->sndcmd
[1], &x
, sizeof(x
));
791 * handler for incoming calls. Either autoanswer, or start ringing
793 static int oss_call(struct ast_channel
*c
, char *dest
, int timeout
)
795 struct chan_oss_pvt
*o
= c
->tech_pvt
;
796 struct ast_frame f
= { 0, };
798 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
);
800 ast_verbose(" << Auto-answered >> \n");
801 f
.frametype
= AST_FRAME_CONTROL
;
802 f
.subclass
= AST_CONTROL_ANSWER
;
803 ast_queue_frame(c
, &f
);
805 ast_verbose("<< Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
806 f
.frametype
= AST_FRAME_CONTROL
;
807 f
.subclass
= AST_CONTROL_RINGING
;
808 ast_queue_frame(c
, &f
);
809 ring(o
, AST_CONTROL_RING
);
815 * remote side answered the phone
817 static int oss_answer(struct ast_channel
*c
)
819 struct chan_oss_pvt
*o
= c
->tech_pvt
;
821 ast_verbose(" << Console call has been answered >> \n");
823 /* play an answer tone (XXX do we really need it ?) */
824 ring(o
, AST_CONTROL_ANSWER
);
826 ast_setstate(c
, AST_STATE_UP
);
832 static int oss_hangup(struct ast_channel
*c
)
834 struct chan_oss_pvt
*o
= c
->tech_pvt
;
840 ast_verbose(" << Hangup on console >> \n");
841 ast_module_unref(ast_module_info
->self
);
843 if (o
->autoanswer
|| o
->autohangup
) {
844 /* Assume auto-hangup too */
846 setformat(o
, O_CLOSE
);
848 /* Make congestion noise */
849 ring(o
, AST_CONTROL_CONGESTION
);
855 /* used for data coming from the network */
856 static int oss_write(struct ast_channel
*c
, struct ast_frame
*f
)
859 struct chan_oss_pvt
*o
= c
->tech_pvt
;
861 /* Immediately return if no sound is enabled */
864 /* Stop any currently playing sound */
867 * we could receive a block which is not a multiple of our
868 * FRAME_SIZE, so buffer it locally and write to the device
869 * in FRAME_SIZE chunks.
870 * Keep the residue stored for future use.
872 src
= 0; /* read position into f->data */
873 while (src
< f
->datalen
) {
874 /* Compute spare room in the buffer */
875 int l
= sizeof(o
->oss_write_buf
) - o
->oss_write_dst
;
877 if (f
->datalen
- src
>= l
) { /* enough to fill a frame */
878 memcpy(o
->oss_write_buf
+ o
->oss_write_dst
, f
->data
+ src
, l
);
879 soundcard_writeframe(o
, (short *) o
->oss_write_buf
);
881 o
->oss_write_dst
= 0;
882 } else { /* copy residue */
883 l
= f
->datalen
- src
;
884 memcpy(o
->oss_write_buf
+ o
->oss_write_dst
, f
->data
+ src
, l
);
885 src
+= l
; /* but really, we are done */
886 o
->oss_write_dst
+= l
;
892 static struct ast_frame
*oss_read(struct ast_channel
*c
)
895 struct chan_oss_pvt
*o
= c
->tech_pvt
;
896 struct ast_frame
*f
= &o
->read_f
;
898 /* XXX can be simplified returning &ast_null_frame */
899 /* prepare a NULL frame in case we don't have enough data to return */
900 bzero(f
, sizeof(struct ast_frame
));
901 f
->frametype
= AST_FRAME_NULL
;
902 f
->src
= oss_tech
.type
;
904 res
= read(o
->sounddev
, o
->oss_read_buf
+ o
->readpos
, sizeof(o
->oss_read_buf
) - o
->readpos
);
905 if (res
< 0) /* audio data not ready, return a NULL frame */
909 if (o
->readpos
< sizeof(o
->oss_read_buf
)) /* not enough samples */
915 o
->readpos
= AST_FRIENDLY_OFFSET
; /* reset read pointer for next frame */
916 if (c
->_state
!= AST_STATE_UP
) /* drop data if frame is not up */
918 /* ok we can build and deliver the frame to the caller */
919 f
->frametype
= AST_FRAME_VOICE
;
920 f
->subclass
= AST_FORMAT_SLINEAR
;
921 f
->samples
= FRAME_SIZE
;
922 f
->datalen
= FRAME_SIZE
* 2;
923 f
->data
= o
->oss_read_buf
+ AST_FRIENDLY_OFFSET
;
924 if (o
->boost
!= BOOST_SCALE
) { /* scale and clip values */
926 int16_t *p
= (int16_t *) f
->data
;
927 for (i
= 0; i
< f
->samples
; i
++) {
928 x
= (p
[i
] * o
->boost
) / BOOST_SCALE
;
937 f
->offset
= AST_FRIENDLY_OFFSET
;
941 static int oss_fixup(struct ast_channel
*oldchan
, struct ast_channel
*newchan
)
943 struct chan_oss_pvt
*o
= newchan
->tech_pvt
;
948 static int oss_indicate(struct ast_channel
*c
, int cond
, const void *data
, size_t datalen
)
950 struct chan_oss_pvt
*o
= c
->tech_pvt
;
954 case AST_CONTROL_BUSY
:
955 case AST_CONTROL_CONGESTION
:
956 case AST_CONTROL_RINGING
:
962 o
->nosound
= 0; /* when cursound is -1 nosound must be 0 */
965 case AST_CONTROL_VIDUPDATE
:
968 case AST_CONTROL_HOLD
:
969 ast_verbose(" << Console Has Been Placed on Hold >> \n");
970 ast_moh_start(c
, data
, o
->mohinterpret
);
972 case AST_CONTROL_UNHOLD
:
973 ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
976 case AST_CONTROL_SRCUPDATE
:
979 ast_log(LOG_WARNING
, "Don't know how to display condition %d on %s\n", cond
, c
->name
);
990 * allocate a new channel.
992 static struct ast_channel
*oss_new(struct chan_oss_pvt
*o
, char *ext
, char *ctx
, int state
)
994 struct ast_channel
*c
;
996 c
= ast_channel_alloc(1, state
, o
->cid_num
, o
->cid_name
, "", ext
, ctx
, 0, "Console/%s", o
->device
+ 5);
1000 if (o
->sounddev
< 0)
1001 setformat(o
, O_RDWR
);
1002 c
->fds
[0] = o
->sounddev
; /* -1 if device closed, override later */
1003 c
->nativeformats
= AST_FORMAT_SLINEAR
;
1004 c
->readformat
= AST_FORMAT_SLINEAR
;
1005 c
->writeformat
= AST_FORMAT_SLINEAR
;
1008 if (!ast_strlen_zero(o
->language
))
1009 ast_string_field_set(c
, language
, o
->language
);
1010 /* Don't use ast_set_callerid() here because it will
1011 * generate a needless NewCallerID event */
1012 c
->cid
.cid_ani
= ast_strdup(o
->cid_num
);
1013 if (!ast_strlen_zero(ext
))
1014 c
->cid
.cid_dnid
= ast_strdup(ext
);
1017 ast_module_ref(ast_module_info
->self
);
1018 ast_jb_configure(c
, &global_jbconf
);
1019 if (state
!= AST_STATE_DOWN
) {
1020 if (ast_pbx_start(c
)) {
1021 ast_log(LOG_WARNING
, "Unable to start PBX on %s\n", c
->name
);
1023 o
->owner
= c
= NULL
;
1024 /* XXX what about the channel itself ? */
1025 /* XXX what about usecnt ? */
1032 static struct ast_channel
*oss_request(const char *type
, int format
, void *data
, int *cause
)
1034 struct ast_channel
*c
;
1035 struct chan_oss_pvt
*o
= find_desc(data
);
1037 ast_log(LOG_WARNING
, "oss_request ty <%s> data 0x%p <%s>\n", type
, data
, (char *) data
);
1039 ast_log(LOG_NOTICE
, "Device %s not found\n", (char *) data
);
1040 /* XXX we could default to 'dsp' perhaps ? */
1043 if ((format
& AST_FORMAT_SLINEAR
) == 0) {
1044 ast_log(LOG_NOTICE
, "Format 0x%x unsupported\n", format
);
1048 ast_log(LOG_NOTICE
, "Already have a call (chan %p) on the OSS channel\n", o
->owner
);
1049 *cause
= AST_CAUSE_BUSY
;
1052 c
= oss_new(o
, NULL
, NULL
, AST_STATE_DOWN
);
1054 ast_log(LOG_WARNING
, "Unable to create new OSS channel\n");
1060 static int console_autoanswer_deprecated(int fd
, int argc
, char *argv
[])
1062 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1065 ast_cli(fd
, "Auto answer is %s.\n", o
->autoanswer
? "on" : "off");
1066 return RESULT_SUCCESS
;
1069 return RESULT_SHOWUSAGE
;
1071 ast_log(LOG_WARNING
, "Cannot find device %s (should not happen!)\n", oss_active
);
1072 return RESULT_FAILURE
;
1074 if (!strcasecmp(argv
[1], "on"))
1076 else if (!strcasecmp(argv
[1], "off"))
1079 return RESULT_SHOWUSAGE
;
1080 return RESULT_SUCCESS
;
1083 static int console_autoanswer(int fd
, int argc
, char *argv
[])
1085 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1088 ast_cli(fd
, "Auto answer is %s.\n", o
->autoanswer
? "on" : "off");
1089 return RESULT_SUCCESS
;
1092 return RESULT_SHOWUSAGE
;
1094 ast_log(LOG_WARNING
, "Cannot find device %s (should not happen!)\n",
1096 return RESULT_FAILURE
;
1098 if (!strcasecmp(argv
[2], "on"))
1100 else if (!strcasecmp(argv
[2], "off"))
1103 return RESULT_SHOWUSAGE
;
1104 return RESULT_SUCCESS
;
1107 static char *autoanswer_complete_deprecated(const char *line
, const char *word
, int pos
, int state
)
1109 static char *choices
[] = { "on", "off", NULL
};
1111 return (pos
!= 2) ? NULL
: ast_cli_complete(word
, choices
, state
);
1114 static char *autoanswer_complete(const char *line
, const char *word
, int pos
, int state
)
1116 static char *choices
[] = { "on", "off", NULL
};
1118 return (pos
!= 3) ? NULL
: ast_cli_complete(word
, choices
, state
);
1121 static char autoanswer_usage
[] =
1122 "Usage: console autoanswer [on|off]\n"
1123 " Enables or disables autoanswer feature. If used without\n"
1124 " argument, displays the current on/off status of autoanswer.\n"
1125 " The default value of autoanswer is in 'oss.conf'.\n";
1128 * answer command from the console
1130 static int console_answer_deprecated(int fd
, int argc
, char *argv
[])
1132 struct ast_frame f
= { AST_FRAME_CONTROL
, AST_CONTROL_ANSWER
};
1133 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1136 return RESULT_SHOWUSAGE
;
1138 ast_cli(fd
, "No one is calling us\n");
1139 return RESULT_FAILURE
;
1144 ast_queue_frame(o
->owner
, &f
);
1146 /* XXX do we really need it ? considering we shut down immediately... */
1147 ring(o
, AST_CONTROL_ANSWER
);
1149 return RESULT_SUCCESS
;
1152 static int console_answer(int fd
, int argc
, char *argv
[])
1154 struct ast_frame f
= { AST_FRAME_CONTROL
, AST_CONTROL_ANSWER
};
1155 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1158 return RESULT_SHOWUSAGE
;
1160 ast_cli(fd
, "No one is calling us\n");
1161 return RESULT_FAILURE
;
1166 ast_queue_frame(o
->owner
, &f
);
1168 /* XXX do we really need it ? considering we shut down immediately... */
1169 ring(o
, AST_CONTROL_ANSWER
);
1171 return RESULT_SUCCESS
;
1174 static char answer_usage
[] =
1175 "Usage: console answer\n"
1176 " Answers an incoming call on the console (OSS) channel.\n";
1179 * concatenate all arguments into a single string. argv is NULL-terminated
1180 * so we can use it right away
1182 static int console_sendtext_deprecated(int fd
, int argc
, char *argv
[])
1184 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1185 char buf
[TEXT_SIZE
];
1188 return RESULT_SHOWUSAGE
;
1190 ast_cli(fd
, "Not in a call\n");
1191 return RESULT_FAILURE
;
1193 ast_join(buf
, sizeof(buf
) - 1, argv
+ 2);
1194 if (!ast_strlen_zero(buf
)) {
1195 struct ast_frame f
= { 0, };
1196 int i
= strlen(buf
);
1198 f
.frametype
= AST_FRAME_TEXT
;
1202 ast_queue_frame(o
->owner
, &f
);
1204 return RESULT_SUCCESS
;
1207 static int console_sendtext(int fd
, int argc
, char *argv
[])
1209 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1210 char buf
[TEXT_SIZE
];
1213 return RESULT_SHOWUSAGE
;
1215 ast_cli(fd
, "Not in a call\n");
1216 return RESULT_FAILURE
;
1218 ast_join(buf
, sizeof(buf
) - 1, argv
+ 3);
1219 if (!ast_strlen_zero(buf
)) {
1220 struct ast_frame f
= { 0, };
1221 int i
= strlen(buf
);
1223 f
.frametype
= AST_FRAME_TEXT
;
1227 ast_queue_frame(o
->owner
, &f
);
1229 return RESULT_SUCCESS
;
1232 static char sendtext_usage
[] =
1233 "Usage: console send text <message>\n"
1234 " Sends a text message for display on the remote terminal.\n";
1236 static int console_hangup_deprecated(int fd
, int argc
, char *argv
[])
1238 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1241 return RESULT_SHOWUSAGE
;
1244 if (!o
->owner
&& !o
->hookstate
) { /* XXX maybe only one ? */
1245 ast_cli(fd
, "No call to hang up\n");
1246 return RESULT_FAILURE
;
1250 ast_queue_hangup(o
->owner
);
1251 setformat(o
, O_CLOSE
);
1252 return RESULT_SUCCESS
;
1255 static int console_hangup(int fd
, int argc
, char *argv
[])
1257 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1260 return RESULT_SHOWUSAGE
;
1263 if (!o
->owner
&& !o
->hookstate
) { /* XXX maybe only one ? */
1264 ast_cli(fd
, "No call to hang up\n");
1265 return RESULT_FAILURE
;
1269 ast_queue_hangup(o
->owner
);
1270 setformat(o
, O_CLOSE
);
1271 return RESULT_SUCCESS
;
1274 static char hangup_usage
[] =
1275 "Usage: console hangup\n"
1276 " Hangs up any call currently placed on the console.\n";
1278 static int console_flash_deprecated(int fd
, int argc
, char *argv
[])
1280 struct ast_frame f
= { AST_FRAME_CONTROL
, AST_CONTROL_FLASH
};
1281 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1284 return RESULT_SHOWUSAGE
;
1286 o
->nosound
= 0; /* when cursound is -1 nosound must be 0 */
1287 if (!o
->owner
) { /* XXX maybe !o->hookstate too ? */
1288 ast_cli(fd
, "No call to flash\n");
1289 return RESULT_FAILURE
;
1292 if (o
->owner
) /* XXX must be true, right ? */
1293 ast_queue_frame(o
->owner
, &f
);
1294 return RESULT_SUCCESS
;
1297 static int console_flash(int fd
, int argc
, char *argv
[])
1299 struct ast_frame f
= { AST_FRAME_CONTROL
, AST_CONTROL_FLASH
};
1300 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1303 return RESULT_SHOWUSAGE
;
1305 o
->nosound
= 0; /* when cursound is -1 nosound must be 0 */
1306 if (!o
->owner
) { /* XXX maybe !o->hookstate too ? */
1307 ast_cli(fd
, "No call to flash\n");
1308 return RESULT_FAILURE
;
1311 if (o
->owner
) /* XXX must be true, right ? */
1312 ast_queue_frame(o
->owner
, &f
);
1313 return RESULT_SUCCESS
;
1316 static char flash_usage
[] =
1317 "Usage: console flash\n"
1318 " Flashes the call currently placed on the console.\n";
1320 static int console_dial_deprecated(int fd
, int argc
, char *argv
[])
1322 char *s
= NULL
, *mye
= NULL
, *myc
= NULL
;
1323 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1325 if (argc
!= 1 && argc
!= 2)
1326 return RESULT_SHOWUSAGE
;
1327 if (o
->owner
) { /* already in a call */
1329 struct ast_frame f
= { AST_FRAME_DTMF
, 0 };
1331 if (argc
== 1) { /* argument is mandatory here */
1332 ast_cli(fd
, "Already in a call. You can only dial digits until you hangup.\n");
1333 return RESULT_FAILURE
;
1336 /* send the string one char at a time */
1337 for (i
= 0; i
< strlen(s
); i
++) {
1339 ast_queue_frame(o
->owner
, &f
);
1341 return RESULT_SUCCESS
;
1343 /* if we have an argument split it into extension and context */
1345 s
= ast_ext_ctx(argv
[1], &mye
, &myc
);
1346 /* supply default values if needed */
1351 if (ast_exists_extension(NULL
, myc
, mye
, 1, NULL
)) {
1353 oss_new(o
, mye
, myc
, AST_STATE_RINGING
);
1355 ast_cli(fd
, "No such extension '%s' in context '%s'\n", mye
, myc
);
1358 return RESULT_SUCCESS
;
1361 static int console_dial(int fd
, int argc
, char *argv
[])
1363 char *s
= NULL
, *mye
= NULL
, *myc
= NULL
;
1364 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1366 if (argc
!= 2 && argc
!= 3)
1367 return RESULT_SHOWUSAGE
;
1368 if (o
->owner
) { /* already in a call */
1370 struct ast_frame f
= { AST_FRAME_DTMF
, 0 };
1372 if (argc
== 2) { /* argument is mandatory here */
1373 ast_cli(fd
, "Already in a call. You can only dial digits until you hangup.\n");
1374 return RESULT_FAILURE
;
1377 /* send the string one char at a time */
1378 for (i
= 0; i
< strlen(s
); i
++) {
1380 ast_queue_frame(o
->owner
, &f
);
1382 return RESULT_SUCCESS
;
1384 /* if we have an argument split it into extension and context */
1386 s
= ast_ext_ctx(argv
[2], &mye
, &myc
);
1387 /* supply default values if needed */
1392 if (ast_exists_extension(NULL
, myc
, mye
, 1, NULL
)) {
1394 oss_new(o
, mye
, myc
, AST_STATE_RINGING
);
1396 ast_cli(fd
, "No such extension '%s' in context '%s'\n", mye
, myc
);
1399 return RESULT_SUCCESS
;
1402 static char dial_usage
[] =
1403 "Usage: console dial [extension[@context]]\n"
1404 " Dials a given extension (and context if specified)\n";
1406 static int __console_mute_unmute(int mute
)
1408 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1411 return RESULT_SUCCESS
;
1414 static int console_mute_deprecated(int fd
, int argc
, char *argv
[])
1417 return RESULT_SHOWUSAGE
;
1419 return __console_mute_unmute(1);
1422 static int console_mute(int fd
, int argc
, char *argv
[])
1425 return RESULT_SHOWUSAGE
;
1427 return __console_mute_unmute(1);
1430 static char mute_usage
[] =
1431 "Usage: console mute\nMutes the microphone\n";
1433 static int console_unmute_deprecated(int fd
, int argc
, char *argv
[])
1436 return RESULT_SHOWUSAGE
;
1438 return __console_mute_unmute(0);
1441 static int console_unmute(int fd
, int argc
, char *argv
[])
1444 return RESULT_SHOWUSAGE
;
1446 return __console_mute_unmute(0);
1449 static char unmute_usage
[] =
1450 "Usage: console unmute\nUnmutes the microphone\n";
1452 static int console_transfer_deprecated(int fd
, int argc
, char *argv
[])
1454 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1455 struct ast_channel
*b
= NULL
;
1456 char *tmp
, *ext
, *ctx
;
1459 return RESULT_SHOWUSAGE
;
1461 return RESULT_FAILURE
;
1462 if (o
->owner
==NULL
|| (b
= ast_bridged_channel(o
->owner
)) == NULL
) {
1463 ast_cli(fd
, "There is no call to transfer\n");
1464 return RESULT_SUCCESS
;
1467 tmp
= ast_ext_ctx(argv
[1], &ext
, &ctx
);
1468 if (ctx
== NULL
) /* supply default context if needed */
1469 ctx
= o
->owner
->context
;
1470 if (!ast_exists_extension(b
, ctx
, ext
, 1, b
->cid
.cid_num
))
1471 ast_cli(fd
, "No such extension exists\n");
1473 ast_cli(fd
, "Whee, transferring %s to %s@%s.\n",
1475 if (ast_async_goto(b
, ctx
, ext
, 1))
1476 ast_cli(fd
, "Failed to transfer :(\n");
1480 return RESULT_SUCCESS
;
1483 static int console_transfer(int fd
, int argc
, char *argv
[])
1485 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1486 struct ast_channel
*b
= NULL
;
1487 char *tmp
, *ext
, *ctx
;
1490 return RESULT_SHOWUSAGE
;
1492 return RESULT_FAILURE
;
1493 if (o
->owner
== NULL
|| (b
= ast_bridged_channel(o
->owner
)) == NULL
) {
1494 ast_cli(fd
, "There is no call to transfer\n");
1495 return RESULT_SUCCESS
;
1498 tmp
= ast_ext_ctx(argv
[2], &ext
, &ctx
);
1499 if (ctx
== NULL
) /* supply default context if needed */
1500 ctx
= o
->owner
->context
;
1501 if (!ast_exists_extension(b
, ctx
, ext
, 1, b
->cid
.cid_num
))
1502 ast_cli(fd
, "No such extension exists\n");
1504 ast_cli(fd
, "Whee, transferring %s to %s@%s.\n", b
->name
, ext
, ctx
);
1505 if (ast_async_goto(b
, ctx
, ext
, 1))
1506 ast_cli(fd
, "Failed to transfer :(\n");
1510 return RESULT_SUCCESS
;
1513 static char transfer_usage
[] =
1514 "Usage: console transfer <extension>[@context]\n"
1515 " Transfers the currently connected call to the given extension (and\n"
1516 "context if specified)\n";
1518 static int console_active_deprecated(int fd
, int argc
, char *argv
[])
1521 ast_cli(fd
, "active console is [%s]\n", oss_active
);
1523 return RESULT_SHOWUSAGE
;
1525 struct chan_oss_pvt
*o
;
1526 if (strcmp(argv
[1], "show") == 0) {
1527 for (o
= oss_default
.next
; o
; o
= o
->next
)
1528 ast_cli(fd
, "device [%s] exists\n", o
->name
);
1529 return RESULT_SUCCESS
;
1531 o
= find_desc(argv
[1]);
1533 ast_cli(fd
, "No device [%s] exists\n", argv
[1]);
1535 oss_active
= o
->name
;
1537 return RESULT_SUCCESS
;
1540 static int console_active(int fd
, int argc
, char *argv
[])
1543 ast_cli(fd
, "active console is [%s]\n", oss_active
);
1545 return RESULT_SHOWUSAGE
;
1547 struct chan_oss_pvt
*o
;
1548 if (strcmp(argv
[2], "show") == 0) {
1549 for (o
= oss_default
.next
; o
; o
= o
->next
)
1550 ast_cli(fd
, "device [%s] exists\n", o
->name
);
1551 return RESULT_SUCCESS
;
1553 o
= find_desc(argv
[2]);
1555 ast_cli(fd
, "No device [%s] exists\n", argv
[2]);
1557 oss_active
= o
->name
;
1559 return RESULT_SUCCESS
;
1562 static char active_usage
[] =
1563 "Usage: console active [device]\n"
1564 " If used without a parameter, displays which device is the current\n"
1565 "console. If a device is specified, the console sound device is changed to\n"
1566 "the device specified.\n";
1569 * store the boost factor
1571 static void store_boost(struct chan_oss_pvt
*o
, char *s
)
1574 if (sscanf(s
, "%lf", &boost
) != 1) {
1575 ast_log(LOG_WARNING
, "invalid boost <%s>\n", s
);
1578 if (boost
< -BOOST_MAX
) {
1579 ast_log(LOG_WARNING
, "boost %s too small, using %d\n", s
, -BOOST_MAX
);
1581 } else if (boost
> BOOST_MAX
) {
1582 ast_log(LOG_WARNING
, "boost %s too large, using %d\n", s
, BOOST_MAX
);
1585 boost
= exp(log(10) * boost
/ 20) * BOOST_SCALE
;
1587 ast_log(LOG_WARNING
, "setting boost %s to %d\n", s
, o
->boost
);
1590 static int do_boost(int fd
, int argc
, char *argv
[])
1592 struct chan_oss_pvt
*o
= find_desc(oss_active
);
1595 ast_cli(fd
, "boost currently %5.1f\n", 20 * log10(((double) o
->boost
/ (double) BOOST_SCALE
)));
1597 store_boost(o
, argv
[2]);
1598 return RESULT_SUCCESS
;
1601 static struct ast_cli_entry cli_oss_answer_deprecated
= {
1603 console_answer_deprecated
, NULL
,
1606 static struct ast_cli_entry cli_oss_hangup_deprecated
= {
1608 console_hangup_deprecated
, NULL
,
1611 static struct ast_cli_entry cli_oss_flash_deprecated
= {
1613 console_flash_deprecated
, NULL
,
1616 static struct ast_cli_entry cli_oss_dial_deprecated
= {
1618 console_dial_deprecated
, NULL
,
1621 static struct ast_cli_entry cli_oss_mute_deprecated
= {
1623 console_mute_deprecated
, NULL
,
1626 static struct ast_cli_entry cli_oss_unmute_deprecated
= {
1628 console_unmute_deprecated
, NULL
,
1631 static struct ast_cli_entry cli_oss_transfer_deprecated
= {
1632 { "transfer", NULL
},
1633 console_transfer_deprecated
, NULL
,
1636 static struct ast_cli_entry cli_oss_send_text_deprecated
= {
1637 { "send", "text", NULL
},
1638 console_sendtext_deprecated
, NULL
,
1641 static struct ast_cli_entry cli_oss_autoanswer_deprecated
= {
1642 { "autoanswer", NULL
},
1643 console_autoanswer_deprecated
, NULL
,
1644 NULL
, autoanswer_complete_deprecated
};
1646 static struct ast_cli_entry cli_oss_boost_deprecated
= {
1647 { "oss", "boost", NULL
},
1651 static struct ast_cli_entry cli_oss_active_deprecated
= {
1652 { "console", NULL
},
1653 console_active_deprecated
, NULL
,
1656 static struct ast_cli_entry cli_oss
[] = {
1657 { { "console", "answer", NULL
},
1658 console_answer
, "Answer an incoming console call",
1659 answer_usage
, NULL
, &cli_oss_answer_deprecated
},
1661 { { "console", "hangup", NULL
},
1662 console_hangup
, "Hangup a call on the console",
1663 hangup_usage
, NULL
, &cli_oss_hangup_deprecated
},
1665 { { "console", "flash", NULL
},
1666 console_flash
, "Flash a call on the console",
1667 flash_usage
, NULL
, &cli_oss_flash_deprecated
},
1669 { { "console", "dial", NULL
},
1670 console_dial
, "Dial an extension on the console",
1671 dial_usage
, NULL
, &cli_oss_dial_deprecated
},
1673 { { "console", "mute", NULL
},
1674 console_mute
, "Disable mic input",
1675 mute_usage
, NULL
, &cli_oss_mute_deprecated
},
1677 { { "console", "unmute", NULL
},
1678 console_unmute
, "Enable mic input",
1679 unmute_usage
, NULL
, &cli_oss_unmute_deprecated
},
1681 { { "console", "transfer", NULL
},
1682 console_transfer
, "Transfer a call to a different extension",
1683 transfer_usage
, NULL
, &cli_oss_transfer_deprecated
},
1685 { { "console", "send", "text", NULL
},
1686 console_sendtext
, "Send text to the remote device",
1687 sendtext_usage
, NULL
, &cli_oss_send_text_deprecated
},
1689 { { "console", "autoanswer", NULL
},
1690 console_autoanswer
, "Sets/displays autoanswer",
1691 autoanswer_usage
, autoanswer_complete
, &cli_oss_autoanswer_deprecated
},
1693 { { "console", "boost", NULL
},
1694 do_boost
, "Sets/displays mic boost in dB",
1695 NULL
, NULL
, &cli_oss_boost_deprecated
},
1697 { { "console", "active", NULL
},
1698 console_active
, "Sets/displays active console",
1699 active_usage
, NULL
, &cli_oss_active_deprecated
},
1703 * store the mixer argument from the config file, filtering possibly
1704 * invalid or dangerous values (the string is used as argument for
1705 * system("mixer %s")
1707 static void store_mixer(struct chan_oss_pvt
*o
, char *s
)
1711 for (i
= 0; i
< strlen(s
); i
++) {
1712 if (!isalnum(s
[i
]) && index(" \t-/", s
[i
]) == NULL
) {
1713 ast_log(LOG_WARNING
, "Suspect char %c in mixer cmd, ignoring:\n\t%s\n", s
[i
], s
);
1719 o
->mixer_cmd
= ast_strdup(s
);
1720 ast_log(LOG_WARNING
, "setting mixer %s\n", s
);
1724 * store the callerid components
1726 static void store_callerid(struct chan_oss_pvt
*o
, char *s
)
1728 ast_callerid_split(s
, o
->cid_name
, sizeof(o
->cid_name
), o
->cid_num
, sizeof(o
->cid_num
));
1732 * grab fields from the config file, init the descriptor and open the device.
1734 static struct chan_oss_pvt
*store_config(struct ast_config
*cfg
, char *ctg
)
1736 struct ast_variable
*v
;
1737 struct chan_oss_pvt
*o
;
1743 if (!(o
= ast_calloc(1, sizeof(*o
))))
1746 /* "general" is also the default thing */
1747 if (strcmp(ctg
, "general") == 0) {
1748 o
->name
= ast_strdup("dsp");
1749 oss_active
= o
->name
;
1752 o
->name
= ast_strdup(ctg
);
1755 strcpy(o
->mohinterpret
, "default");
1757 o
->lastopen
= ast_tvnow(); /* don't leave it 0 or tvdiff may wrap */
1758 /* fill other fields from configuration */
1759 for (v
= ast_variable_browse(cfg
, ctg
); v
; v
= v
->next
) {
1760 M_START(v
->name
, v
->value
);
1762 /* handle jb conf */
1763 if (!ast_jb_read_conf(&global_jbconf
, v
->name
, v
->value
))
1766 M_BOOL("autoanswer", o
->autoanswer
)
1767 M_BOOL("autohangup", o
->autohangup
)
1768 M_BOOL("overridecontext", o
->overridecontext
)
1769 M_STR("device", o
->device
)
1770 M_UINT("frags", o
->frags
)
1771 M_UINT("debug", oss_debug
)
1772 M_UINT("queuesize", o
->queuesize
)
1773 M_STR("context", o
->ctx
)
1774 M_STR("language", o
->language
)
1775 M_STR("mohinterpret", o
->mohinterpret
)
1776 M_STR("extension", o
->ext
)
1777 M_F("mixer", store_mixer(o
, v
->value
))
1778 M_F("callerid", store_callerid(o
, v
->value
))
1779 M_F("boost", store_boost(o
, v
->value
))
1783 if (ast_strlen_zero(o
->device
))
1784 ast_copy_string(o
->device
, DEV_DSP
, sizeof(o
->device
));
1788 asprintf(&cmd
, "mixer %s", o
->mixer_cmd
);
1789 ast_log(LOG_WARNING
, "running [%s]\n", cmd
);
1793 if (o
== &oss_default
) /* we are done with the default */
1798 if (setformat(o
, O_RDWR
) < 0) { /* open device */
1799 if (option_verbose
> 0) {
1800 ast_verbose(VERBOSE_PREFIX_2
"Device %s not detected\n", ctg
);
1801 ast_verbose(VERBOSE_PREFIX_2
"Turn off OSS support by adding " "'noload=chan_oss.so' in /etc/asterisk/modules.conf\n");
1805 if (o
->duplex
!= M_FULL
)
1806 ast_log(LOG_WARNING
, "XXX I don't work right with non " "full-duplex sound cards XXX\n");
1807 #endif /* TRYOPEN */
1808 if (pipe(o
->sndcmd
) != 0) {
1809 ast_log(LOG_ERROR
, "Unable to create pipe\n");
1812 ast_pthread_create_background(&o
->sthread
, NULL
, sound_thread
, o
);
1813 /* link into list of devices */
1814 if (o
!= &oss_default
) {
1815 o
->next
= oss_default
.next
;
1816 oss_default
.next
= o
;
1821 if (o
!= &oss_default
)
1826 static int load_module(void)
1828 struct ast_config
*cfg
= NULL
;
1831 /* Copy the default jb config over global_jbconf */
1832 memcpy(&global_jbconf
, &default_jbconf
, sizeof(struct ast_jb_conf
));
1834 /* load config file */
1835 if (!(cfg
= ast_config_load(config
))) {
1836 ast_log(LOG_NOTICE
, "Unable to load config %s\n", config
);
1837 return AST_MODULE_LOAD_DECLINE
;
1841 store_config(cfg
, ctg
);
1842 } while ( (ctg
= ast_category_browse(cfg
, ctg
)) != NULL
);
1844 ast_config_destroy(cfg
);
1846 if (find_desc(oss_active
) == NULL
) {
1847 ast_log(LOG_NOTICE
, "Device %s not found\n", oss_active
);
1848 /* XXX we could default to 'dsp' perhaps ? */
1849 /* XXX should cleanup allocated memory etc. */
1850 return AST_MODULE_LOAD_FAILURE
;
1853 if (ast_channel_register(&oss_tech
)) {
1854 ast_log(LOG_ERROR
, "Unable to register channel type 'OSS'\n");
1855 return AST_MODULE_LOAD_FAILURE
;
1858 ast_cli_register_multiple(cli_oss
, sizeof(cli_oss
) / sizeof(struct ast_cli_entry
));
1860 return AST_MODULE_LOAD_SUCCESS
;
1864 static int unload_module(void)
1866 struct chan_oss_pvt
*o
;
1868 ast_channel_unregister(&oss_tech
);
1869 ast_cli_unregister_multiple(cli_oss
, sizeof(cli_oss
) / sizeof(struct ast_cli_entry
));
1871 for (o
= oss_default
.next
; o
; o
= o
->next
) {
1873 if (o
->sndcmd
[0] > 0) {
1874 close(o
->sndcmd
[0]);
1875 close(o
->sndcmd
[1]);
1878 ast_softhangup(o
->owner
, AST_SOFTHANGUP_APPUNLOAD
);
1879 if (o
->owner
) /* XXX how ??? */
1881 /* XXX what about the thread ? */
1882 /* XXX what about the memory allocated ? */
1887 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "OSS Console Channel Driver");