44 #define ESTRPIPE EPIPE 47 #include <sys/ioctl.h> 50 #define ALSA_PCM_NEW_HW_PARAMS_API 51 #define ALSA_PCM_NEW_SW_PARAMS_API 52 #include <alsa/asoundlib.h> 75 .resync_threshold = 1000,
83 #define ALSA_INDEV "default" 84 #define ALSA_OUTDEV "default" 85 #define DESIRED_RATE 8000 88 #define FRAME_SIZE 160 89 #define PERIOD_FRAMES 80 94 #define BUFFER_FMT ((buffersize * 10) << 16) | (0x0006); 97 #define MIN_SWITCH_TIME 600 99 #if __BYTE_ORDER == __LITTLE_ENDIAN 100 static snd_pcm_format_t
format = SND_PCM_FORMAT_S16_LE;
102 static snd_pcm_format_t
format = SND_PCM_FORMAT_S16_BE;
113 static const char tdesc[] =
"ALSA Console Channel Driver";
114 static const char config[] =
"alsa.conf";
137 #define MAX_BUFFER_SIZE 100 160 .description =
tdesc,
177 snd_pcm_t *handle =
NULL;
178 snd_pcm_hw_params_t *hwparams =
NULL;
179 snd_pcm_sw_params_t *swparams =
NULL;
182 snd_pcm_uframes_t buffer_size = 0;
184 snd_pcm_uframes_t start_threshold, stop_threshold;
186 err = snd_pcm_open(&handle, dev, stream, SND_PCM_NONBLOCK);
191 ast_debug(1,
"Opening device %s in %s mode\n", dev, (stream == SND_PCM_STREAM_CAPTURE) ?
"read" :
"write");
194 hwparams =
ast_alloca(snd_pcm_hw_params_sizeof());
195 memset(hwparams, 0, snd_pcm_hw_params_sizeof());
196 snd_pcm_hw_params_any(handle, hwparams);
198 err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
202 err = snd_pcm_hw_params_set_format(handle, hwparams,
format);
206 err = snd_pcm_hw_params_set_channels(handle, hwparams, 1);
211 err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, &direction);
216 err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, &direction);
218 ast_log(
LOG_ERROR,
"period_size(%lu frames) is bad: %s\n", period_size, snd_strerror(err));
220 ast_debug(1,
"Period size is %d\n", err);
223 buffer_size = 4096 * 2;
224 err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size);
226 ast_log(
LOG_WARNING,
"Problem setting buffer size of %lu: %s\n", buffer_size, snd_strerror(err));
228 ast_debug(1,
"Buffer size is set to %d frames\n", err);
231 err = snd_pcm_hw_params(handle, hwparams);
233 ast_log(
LOG_ERROR,
"Couldn't set the new hw params: %s\n", snd_strerror(err));
235 swparams =
ast_alloca(snd_pcm_sw_params_sizeof());
236 memset(swparams, 0, snd_pcm_sw_params_sizeof());
237 snd_pcm_sw_params_current(handle, swparams);
239 if (stream == SND_PCM_STREAM_PLAYBACK)
240 start_threshold = period_size;
244 err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold);
248 if (stream == SND_PCM_STREAM_PLAYBACK)
249 stop_threshold = buffer_size;
251 stop_threshold = buffer_size;
253 err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold);
257 err = snd_pcm_sw_params(handle, swparams);
261 err = snd_pcm_poll_descriptors_count(handle);
263 ast_log(
LOG_ERROR,
"Unable to get a poll descriptors count, error is %s\n", snd_strerror(err));
265 ast_debug(1,
"Can't handle more than one device\n");
268 snd_pcm_poll_descriptors(handle, &pfd, err);
269 ast_debug(1,
"Acquired fd %d from the poll descriptor\n", pfd.fd);
271 if (stream == SND_PCM_STREAM_CAPTURE)
302 ast_verbose(
" << Console Received digit %c of duration %u ms >> \n",
312 ast_verbose(
" << Console Received text %s >> \n", text);
330 ast_verbose(
" << Call placed to '%s' on console >> \n", dest);
343 ast_verbose(
" << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
364 ast_verbose(
" << Console call has been answered >> \n");
393 static char sizbuf[8000];
394 static int sizpos = 0;
398 snd_pcm_state_t
state;
403 if (f->
datalen >
sizeof(sizbuf) - sizpos) {
410 if (state == SND_PCM_STATE_XRUN)
412 while ((res = snd_pcm_writei(
alsa.
ocard, sizbuf, len / 2)) == -EAGAIN) {
420 while ((res = snd_pcm_writei(
alsa.
ocard, sizbuf, len / 2)) == -EAGAIN) {
423 if (res != len / 2) {
426 }
else if (res < 0) {
439 return res >= 0 ? 0 : res;
448 static int readpos = 0;
450 snd_pcm_state_t
state;
472 if ((state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING)) {
478 r = snd_pcm_readi(
alsa.
icard, buf + readpos, left);
563 ast_verbose(
" << Console Has Been Placed on Hold >> \n");
567 ast_verbose(
" << Console Has Been Retrieved from Hold >> \n");
584 if (!(tmp =
ast_channel_alloc(1, state, 0, 0,
"", p->
exten, p->
context, assignedids, requestor, 0,
"ALSA/%s",
indevname)))
601 ast_channel_language_set(tmp,
language);
650 e->
command =
"console autoanswer [on|off]";
652 "Usage: console autoanswer [on|off]\n" 653 " Enables or disables autoanswer feature. If used without\n" 654 " argument, displays the current on/off status of autoanswer.\n" 655 " The default value of autoanswer is in 'alsa.conf'.\n";
661 if ((a->
argc != 2) && (a->
argc != 3))
668 if (!strcasecmp(a->
argv[2],
"on"))
670 else if (!strcasecmp(a->
argv[2],
"off"))
688 "Usage: console answer\n" 689 " Answers an incoming call on the console (ALSA) channel.\n";
702 ast_cli(a->
fd,
"No one is calling us\n");
733 e->
command =
"console send text";
735 "Usage: console send text <message>\n" 736 " Sends a text message for display on the remote terminal.\n";
752 char text2send[256] =
"";
754 while (tmparg < a->argc) {
755 strncat(text2send, a->
argv[tmparg++],
sizeof(text2send) - strlen(text2send) - 1);
756 strncat(text2send,
" ",
sizeof(text2send) - strlen(text2send) - 1);
759 text2send[strlen(text2send) - 1] =
'\n';
761 f.
datalen = strlen(text2send) + 1;
783 "Usage: console hangup\n" 784 " Hangs up any call currently placed on the console.\n";
815 char tmp[256], *tmp2;
824 "Usage: console dial [extension[@context]]\n" 825 " Dials a given extension (and context if specified)\n";
831 if ((a->
argc != 2) && (a->
argc != 3))
839 for (d = a->
argv[2]; *d; d++) {
846 ast_cli(a->
fd,
"You're already in a call. You can use this only to dial digits until you hangup\n");
853 char *stringp =
NULL;
858 tmp2 =
strsep(&stringp,
"@");
870 ast_cli(a->
fd,
"No such extension '%s' in context '%s'\n", mye, myc);
885 e->
command =
"console {mute|unmute} [toggle]";
887 "Usage: console {mute|unmute} [toggle]\n" 888 " Mute/unmute the microphone.\n";
900 if (strcasecmp(a->
argv[2],
"toggle"))
909 if (!strcasecmp(a->
argv[1],
"mute")) {
911 }
else if (!strcasecmp(a->
argv[1],
"unmute")) {
986 for (; v; v = v->
next) {
992 if (!strcasecmp(v->
name,
"autoanswer")) {
994 }
else if (!strcasecmp(v->
name,
"mute")) {
996 }
else if (!strcasecmp(v->
name,
"noaudiocapture")) {
998 }
else if (!strcasecmp(v->
name,
"silencesuppression")) {
1000 }
else if (!strcasecmp(v->
name,
"silencethreshold")) {
1002 }
else if (!strcasecmp(v->
name,
"context")) {
1004 }
else if (!strcasecmp(v->
name,
"language")) {
1006 }
else if (!strcasecmp(v->
name,
"extension")) {
1008 }
else if (!strcasecmp(v->
name,
"input_device")) {
1010 }
else if (!strcasecmp(v->
name,
"output_device")) {
1012 }
else if (!strcasecmp(v->
name,
"mohinterpret")) {
1019 ast_verb(2,
"No sound card detected -- console channel will be unavailable\n");
1020 ast_verb(2,
"Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf\n");
struct ast_variable * next
static char * console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct ast_channel * owner
enum sip_cc_notify_state state
static char mohinterpret[MAX_MUSICCLASS]
static char exten[AST_MAX_EXTENSION]
Main Channel structure associated with a channel.
#define AST_CLI_DEFINE(fn, txt,...)
Asterisk main include file. File version handling, generic pbx functions.
static const char tdesc[]
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
static struct ast_channel_tech alsa_tech
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
static int silencethreshold
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
static struct chan_alsa_pvt alsa
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
static int alsa_write(struct ast_channel *chan, struct ast_frame *f)
#define DEADLOCK_AVOIDANCE(lock)
descriptor for a cli entry.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
#define CONFIG_STATUS_FILEINVALID
static struct ast_jb_conf global_jbconf
Structure for variables, used for configurations and for channel variables.
static int noaudiocapture
static int alsa_text(struct ast_channel *c, const char *text)
static int alsa_call(struct ast_channel *c, const char *dest, int timeout)
static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration)
Structure to pass both assignedid values to channel drivers.
ast_channel_state
ast_channel states
static struct ast_channel * alsa_new(struct chan_alsa_pvt *p, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
static char * console_sendtext(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define ast_mutex_lock(a)
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
#define ast_str_alloca(init_len)
void ast_verbose(const char *fmt,...)
static char * console_autoanswer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int alsa_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
Common implementation-independent jitterbuffer stuff.
void ast_cli(int fd, const char *fmt,...)
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
#define ast_verb(level,...)
struct ast_frame_subclass subclass
static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen)
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
#define ast_module_unref(mod)
Release a reference to the module.
#define ast_strlen_zero(foo)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
Configuration File Parser.
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_config_load(filename, flags)
Load a config file.
General Asterisk PBX channel definitions.
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
static struct ast_channel * alsa_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
Asterisk architecture endianess compatibility definitions.
#define AST_MAX_EXTENSION
#define AST_CAUSE_NORMAL_CLEARING
static int load_module(void)
Load the module.
Asterisk internal frame definitions.
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
static int soundcard_init(void)
static char language[MAX_LANGUAGE]
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Core PBX routines and definitions.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
static char outdevname[50]
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static ast_mutex_t alsalock
char context[AST_MAX_CONTEXT]
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
char exten[AST_MAX_EXTENSION]
struct ast_format_cap * capabilities
static char indevname[50]
#define ast_channel_unlock(chan)
static struct ast_cli_entry cli_alsa[]
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Module has failed to load, may be in an inconsistent state.
unsigned int flags
Combination of the AST_JB_ENABLED, AST_JB_FORCED and AST_JB_LOG flags.
static char * console_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Structure used to handle boolean flags.
static struct ast_frame * alsa_read(struct ast_channel *chan)
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
static char * console_mute(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void grab_owner(void)
char * strsep(char **str, const char *delims)
Standard Command Line Interface.
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
const char * ast_channel_name(const struct ast_channel *chan)
static snd_pcm_t * alsa_card_init(char *dev, snd_pcm_stream_t stream)
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
static const char config[]
union ast_frame::@263 data
enum ast_frame_type frametype
#define ast_channel_trylock(chan)
static char * console_answer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char context[AST_MAX_CONTEXT]
struct ast_format * format
#define ASTERISK_GPL_KEY
The text the key() function should return.
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Asterisk module definitions.
static int alsa_answer(struct ast_channel *c)
static snd_pcm_format_t format
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
General jitterbuffer configuration.
#define AST_MUTEX_DEFINE_STATIC(mutex)
static struct ast_jb_conf default_jbconf
static int silencesuppression
static int unload_module(void)
#define ast_mutex_unlock(a)
static int alsa_hangup(struct ast_channel *c)
#define ast_module_ref(mod)
Hold a reference to the module.