Wed Jan 8 2020 09:49:59

Asterisk developer's documentation


chan_alsa.c File Reference

ALSA sound card channel driver. More...

#include "asterisk.h"
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <alsa/asoundlib.h>
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/module.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 "asterisk/poll-compat.h"

Go to the source code of this file.

Data Structures

struct  chan_alsa_pvt
 

Macros

#define ALSA_INDEV   "default"
 
#define ALSA_OUTDEV   "default"
 
#define ALSA_PCM_NEW_HW_PARAMS_API
 
#define ALSA_PCM_NEW_SW_PARAMS_API
 
#define BUFFER_FMT   ((buffersize * 10) << 16) | (0x0006);
 
#define DEBUG   0
 
#define DESIRED_RATE   8000
 
#define FRAME_SIZE   160
 
#define MAX_BUFFER_SIZE   100
 
#define MIN_SWITCH_TIME   600
 
#define PERIOD_FRAMES   80 /* 80 Frames, at 2 bytes each */
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int alsa_answer (struct ast_channel *c)
 
static int alsa_call (struct ast_channel *c, char *dest, int timeout)
 
static snd_pcm_t * alsa_card_init (char *dev, snd_pcm_stream_t stream)
 
static int alsa_digit (struct ast_channel *c, char digit, unsigned int duration)
 
static int alsa_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 
static int alsa_hangup (struct ast_channel *c)
 
static int alsa_indicate (struct ast_channel *chan, int cond, const void *data, size_t datalen)
 
static struct ast_channelalsa_new (struct chan_alsa_pvt *p, int state, const char *linkedid)
 
static struct ast_framealsa_read (struct ast_channel *chan)
 
static struct ast_channelalsa_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
 
static int alsa_text (struct ast_channel *c, const char *text)
 
static int alsa_write (struct ast_channel *chan, struct ast_frame *f)
 
static char * autoanswer_complete (const char *line, const char *word, int pos, int state)
 
static char * console_answer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * console_autoanswer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * console_dial (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * console_hangup (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * console_mute (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * console_sendtext (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static void grab_owner (void)
 
static int load_module (void)
 
static int soundcard_init (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "ALSA 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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, }
 
static struct chan_alsa_pvt alsa
 
static struct ast_channel_tech alsa_tech
 
static ast_mutex_t alsalock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static struct ast_module_infoast_module_info = &__mod_info
 
static int autoanswer = 1
 
static struct ast_cli_entry cli_alsa []
 
static const char config [] = "alsa.conf"
 
static char context [AST_MAX_CONTEXT] = "default"
 
static struct ast_jb_conf default_jbconf
 
static char exten [AST_MAX_EXTENSION] = "s"
 
static snd_pcm_format_t format = SND_PCM_FORMAT_S16_BE
 
static struct ast_jb_conf global_jbconf
 
static int hookstate = 0
 
static char indevname [50] = ALSA_INDEV
 
static char language [MAX_LANGUAGE] = ""
 
static char mohinterpret [MAX_MUSICCLASS]
 
static int mute = 0
 
static int noaudiocapture = 0
 
static char outdevname [50] = ALSA_OUTDEV
 
static int readdev = -1
 
static int silencesuppression = 0
 
static int silencethreshold = 1000
 
static const char tdesc [] = "ALSA Console Channel Driver"
 
static int writedev = -1
 

Detailed Description

ALSA sound card channel driver.

Author
Matthew Fredrickson cresl.nosp@m.in@d.nosp@m.igium.nosp@m..com
See also
  • Config_alsa

Definition in file chan_alsa.c.

Macro Definition Documentation

#define ALSA_INDEV   "default"

Definition at line 74 of file chan_alsa.c.

#define ALSA_OUTDEV   "default"

Definition at line 75 of file chan_alsa.c.

#define ALSA_PCM_NEW_HW_PARAMS_API

Definition at line 43 of file chan_alsa.c.

#define ALSA_PCM_NEW_SW_PARAMS_API

Definition at line 44 of file chan_alsa.c.

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

Definition at line 85 of file chan_alsa.c.

#define DEBUG   0

Definition at line 72 of file chan_alsa.c.

#define DESIRED_RATE   8000

Definition at line 76 of file chan_alsa.c.

Referenced by alsa_card_init().

#define FRAME_SIZE   160

Definition at line 79 of file chan_alsa.c.

Referenced by alsa_read().

#define MAX_BUFFER_SIZE   100

Definition at line 128 of file chan_alsa.c.

#define MIN_SWITCH_TIME   600

Definition at line 88 of file chan_alsa.c.

#define PERIOD_FRAMES   80 /* 80 Frames, at 2 bytes each */

Definition at line 80 of file chan_alsa.c.

Referenced by alsa_card_init().

Function Documentation

static void __reg_module ( void  )
static

Definition at line 1024 of file chan_alsa.c.

static void __unreg_module ( void  )
static

Definition at line 1024 of file chan_alsa.c.

static int alsa_answer ( struct ast_channel c)
static

Definition at line 353 of file chan_alsa.c.

References alsa, alsalock, ast_mutex_lock, ast_mutex_unlock, ast_setstate(), AST_STATE_UP, ast_verbose(), and chan_alsa_pvt::icard.

354 {
356  ast_verbose(" << Console call has been answered >> \n");
358  if (!noaudiocapture) {
359  snd_pcm_prepare(alsa.icard);
360  snd_pcm_start(alsa.icard);
361  }
363 
364  return 0;
365 }
snd_pcm_t * icard
Definition: chan_alsa.c:120
static struct chan_alsa_pvt alsa
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
static int noaudiocapture
Definition: chan_alsa.c:136
#define ast_mutex_lock(a)
Definition: lock.h:155
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int alsa_call ( struct ast_channel c,
char *  dest,
int  timeout 
)
static

Definition at line 317 of file chan_alsa.c.

References alsa, alsalock, ast_channel_unlock, AST_CONTROL_ANSWER, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_indicate(), ast_mutex_lock, ast_mutex_unlock, ast_queue_frame(), ast_verbose(), grab_owner(), chan_alsa_pvt::icard, ast_frame_subclass::integer, chan_alsa_pvt::owner, and ast_frame::subclass.

318 {
319  struct ast_frame f = { AST_FRAME_CONTROL };
320 
322  ast_verbose(" << Call placed to '%s' on console >> \n", dest);
323  if (autoanswer) {
324  ast_verbose(" << Auto-answered >> \n");
325  if (mute) {
326  ast_verbose( " << Muted >> \n" );
327  }
328  grab_owner();
329  if (alsa.owner) {
333  }
334  } else {
335  ast_verbose(" << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
336  grab_owner();
337  if (alsa.owner) {
342  }
343  }
344  if (!noaudiocapture) {
345  snd_pcm_prepare(alsa.icard);
346  snd_pcm_start(alsa.icard);
347  }
349 
350  return 0;
351 }
union ast_frame_subclass subclass
Definition: frame.h:146
struct ast_channel * owner
Definition: chan_alsa.c:117
snd_pcm_t * icard
Definition: chan_alsa.c:120
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4393
static struct chan_alsa_pvt alsa
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
static int noaudiocapture
Definition: chan_alsa.c:136
static int autoanswer
Definition: chan_alsa.c:134
#define ast_mutex_lock(a)
Definition: lock.h:155
static int mute
Definition: chan_alsa.c:135
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static struct ast_format f[]
Definition: format_g726.c:181
static void grab_owner(void)
Definition: chan_alsa.c:310
Data structure associated with a single frame of data.
Definition: frame.h:142
#define ast_mutex_unlock(a)
Definition: lock.h:156
static snd_pcm_t* alsa_card_init ( char *  dev,
snd_pcm_stream_t  stream 
)
static

Definition at line 165 of file chan_alsa.c.

References ast_alloca, ast_debug, ast_log(), DESIRED_RATE, LOG_ERROR, LOG_WARNING, and PERIOD_FRAMES.

Referenced by soundcard_init().

166 {
167  int err;
168  int direction;
169  snd_pcm_t *handle = NULL;
170  snd_pcm_hw_params_t *hwparams = NULL;
171  snd_pcm_sw_params_t *swparams = NULL;
172  struct pollfd pfd;
173  snd_pcm_uframes_t period_size = PERIOD_FRAMES * 4;
174  snd_pcm_uframes_t buffer_size = 0;
175  unsigned int rate = DESIRED_RATE;
176  snd_pcm_uframes_t start_threshold, stop_threshold;
177 
178  err = snd_pcm_open(&handle, dev, stream, SND_PCM_NONBLOCK);
179  if (err < 0) {
180  ast_log(LOG_ERROR, "snd_pcm_open failed: %s\n", snd_strerror(err));
181  return NULL;
182  } else {
183  ast_debug(1, "Opening device %s in %s mode\n", dev, (stream == SND_PCM_STREAM_CAPTURE) ? "read" : "write");
184  }
185 
186  hwparams = ast_alloca(snd_pcm_hw_params_sizeof());
187  memset(hwparams, 0, snd_pcm_hw_params_sizeof());
188  snd_pcm_hw_params_any(handle, hwparams);
189 
190  err = snd_pcm_hw_params_set_access(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
191  if (err < 0)
192  ast_log(LOG_ERROR, "set_access failed: %s\n", snd_strerror(err));
193 
194  err = snd_pcm_hw_params_set_format(handle, hwparams, format);
195  if (err < 0)
196  ast_log(LOG_ERROR, "set_format failed: %s\n", snd_strerror(err));
197 
198  err = snd_pcm_hw_params_set_channels(handle, hwparams, 1);
199  if (err < 0)
200  ast_log(LOG_ERROR, "set_channels failed: %s\n", snd_strerror(err));
201 
202  direction = 0;
203  err = snd_pcm_hw_params_set_rate_near(handle, hwparams, &rate, &direction);
204  if (rate != DESIRED_RATE)
205  ast_log(LOG_WARNING, "Rate not correct, requested %d, got %u\n", DESIRED_RATE, rate);
206 
207  direction = 0;
208  err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, &direction);
209  if (err < 0)
210  ast_log(LOG_ERROR, "period_size(%lu frames) is bad: %s\n", period_size, snd_strerror(err));
211  else {
212  ast_debug(1, "Period size is %d\n", err);
213  }
214 
215  buffer_size = 4096 * 2; /* period_size * 16; */
216  err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size);
217  if (err < 0)
218  ast_log(LOG_WARNING, "Problem setting buffer size of %lu: %s\n", buffer_size, snd_strerror(err));
219  else {
220  ast_debug(1, "Buffer size is set to %d frames\n", err);
221  }
222 
223  err = snd_pcm_hw_params(handle, hwparams);
224  if (err < 0)
225  ast_log(LOG_ERROR, "Couldn't set the new hw params: %s\n", snd_strerror(err));
226 
227  swparams = ast_alloca(snd_pcm_sw_params_sizeof());
228  memset(swparams, 0, snd_pcm_sw_params_sizeof());
229  snd_pcm_sw_params_current(handle, swparams);
230 
231  if (stream == SND_PCM_STREAM_PLAYBACK)
232  start_threshold = period_size;
233  else
234  start_threshold = 1;
235 
236  err = snd_pcm_sw_params_set_start_threshold(handle, swparams, start_threshold);
237  if (err < 0)
238  ast_log(LOG_ERROR, "start threshold: %s\n", snd_strerror(err));
239 
240  if (stream == SND_PCM_STREAM_PLAYBACK)
241  stop_threshold = buffer_size;
242  else
243  stop_threshold = buffer_size;
244 
245  err = snd_pcm_sw_params_set_stop_threshold(handle, swparams, stop_threshold);
246  if (err < 0)
247  ast_log(LOG_ERROR, "stop threshold: %s\n", snd_strerror(err));
248 
249  err = snd_pcm_sw_params(handle, swparams);
250  if (err < 0)
251  ast_log(LOG_ERROR, "sw_params: %s\n", snd_strerror(err));
252 
253  err = snd_pcm_poll_descriptors_count(handle);
254  if (err <= 0)
255  ast_log(LOG_ERROR, "Unable to get a poll descriptors count, error is %s\n", snd_strerror(err));
256  if (err != 1) {
257  ast_debug(1, "Can't handle more than one device\n");
258  }
259 
260  snd_pcm_poll_descriptors(handle, &pfd, err);
261  ast_debug(1, "Acquired fd %d from the poll descriptor\n", pfd.fd);
262 
263  if (stream == SND_PCM_STREAM_CAPTURE)
264  readdev = pfd.fd;
265  else
266  writedev = pfd.fd;
267 
268  return handle;
269 }
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
#define LOG_WARNING
Definition: logger.h:144
#define DESIRED_RATE
Definition: chan_alsa.c:76
static int writedev
Definition: chan_alsa.c:132
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define PERIOD_FRAMES
Definition: chan_alsa.c:80
static snd_pcm_format_t format
Definition: chan_alsa.c:93
static int readdev
Definition: chan_alsa.c:131
static int alsa_digit ( struct ast_channel c,
char  digit,
unsigned int  duration 
)
static

Definition at line 291 of file chan_alsa.c.

References alsalock, ast_mutex_lock, ast_mutex_unlock, and ast_verbose().

292 {
294  ast_verbose(" << Console Received digit %c of duration %u ms >> \n",
295  digit, duration);
297 
298  return 0;
299 }
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
#define ast_mutex_lock(a)
Definition: lock.h:155
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int alsa_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
)
static

Definition at line 526 of file chan_alsa.c.

References alsalock, ast_mutex_lock, ast_mutex_unlock, chan_alsa_pvt::owner, and ast_channel::tech_pvt.

527 {
528  struct chan_alsa_pvt *p = newchan->tech_pvt;
529 
531  p->owner = newchan;
533 
534  return 0;
535 }
struct ast_channel * owner
Definition: chan_alsa.c:117
void * tech_pvt
Definition: channel.h:744
#define ast_mutex_lock(a)
Definition: lock.h:155
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int alsa_hangup ( struct ast_channel c)
static

Definition at line 367 of file chan_alsa.c.

References alsa, alsalock, ast_module_unref(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), chan_alsa_pvt::icard, chan_alsa_pvt::owner, ast_module_info::self, and ast_channel::tech_pvt.

368 {
370  c->tech_pvt = NULL;
371  alsa.owner = NULL;
372  ast_verbose(" << Hangup on console >> \n");
374  hookstate = 0;
375  if (!noaudiocapture) {
376  snd_pcm_drop(alsa.icard);
377  }
379 
380  return 0;
381 }
struct ast_channel * owner
Definition: chan_alsa.c:117
void ast_module_unref(struct ast_module *)
Definition: loader.c:1312
snd_pcm_t * icard
Definition: chan_alsa.c:120
static struct chan_alsa_pvt alsa
void * tech_pvt
Definition: channel.h:744
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
static int noaudiocapture
Definition: chan_alsa.c:136
#define ast_mutex_lock(a)
Definition: lock.h:155
struct ast_module * self
Definition: module.h:227
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
static int hookstate
Definition: chan_alsa.c:112
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int alsa_indicate ( struct ast_channel chan,
int  cond,
const void *  data,
size_t  datalen 
)
static

Definition at line 537 of file chan_alsa.c.

References alsalock, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_verbose(), LOG_WARNING, and ast_channel::name.

538 {
539  int res = 0;
540 
542 
543  switch (cond) {
544  case AST_CONTROL_BUSY:
546  case AST_CONTROL_RINGING:
548  case -1:
549  res = -1; /* Ask for inband indications */
550  break;
555  break;
556  case AST_CONTROL_HOLD:
557  ast_verbose(" << Console Has Been Placed on Hold >> \n");
558  ast_moh_start(chan, data, mohinterpret);
559  break;
560  case AST_CONTROL_UNHOLD:
561  ast_verbose(" << Console Has Been Retrieved from Hold >> \n");
562  ast_moh_stop(chan);
563  break;
564  default:
565  ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, chan->name);
566  res = -1;
567  }
568 
570 
571  return res;
572 }
static char mohinterpret[MAX_MUSICCLASS]
Definition: chan_alsa.c:110
#define LOG_WARNING
Definition: logger.h:144
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:8051
ast_cond_t cond
Definition: app_meetme.c:963
const ast_string_field name
Definition: channel.h:787
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:8040
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_mutex_unlock(a)
Definition: lock.h:156
static struct ast_channel* alsa_new ( struct chan_alsa_pvt p,
int  state,
const char *  linkedid 
)
static

Definition at line 574 of file chan_alsa.c.

References alsa_tech, ast_channel_alloc(), ast_channel_set_fd(), ast_copy_string(), AST_FORMAT_SLINEAR, ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), AST_STATE_DOWN, ast_string_field_set, ast_strlen_zero(), chan_alsa_pvt::context, ast_channel::context, chan_alsa_pvt::exten, ast_channel::exten, global_jbconf, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, chan_alsa_pvt::owner, ast_channel::readformat, ast_module_info::self, ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat.

Referenced by alsa_request(), and console_dial().

575 {
576  struct ast_channel *tmp = NULL;
577 
578  if (!(tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, linkedid, 0, "ALSA/%s", indevname)))
579  return NULL;
580 
581  tmp->tech = &alsa_tech;
582  ast_channel_set_fd(tmp, 0, readdev);
586  tmp->tech_pvt = p;
587  if (!ast_strlen_zero(p->context))
588  ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
589  if (!ast_strlen_zero(p->exten))
590  ast_copy_string(tmp->exten, p->exten, sizeof(tmp->exten));
593  p->owner = tmp;
596  if (state != AST_STATE_DOWN) {
597  if (ast_pbx_start(tmp)) {
598  ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
599  ast_hangup(tmp);
600  tmp = NULL;
601  }
602  }
603 
604  return tmp;
605 }
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
struct ast_channel * owner
Definition: chan_alsa.c:117
Main Channel structure associated with a channel.
Definition: channel.h:742
static struct ast_channel_tech alsa_tech
Definition: chan_alsa.c:149
format_t writeformat
Definition: channel.h:854
void * tech_pvt
Definition: channel.h:744
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define LOG_WARNING
Definition: logger.h:144
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:5879
static struct ast_jb_conf global_jbconf
Definition: chan_alsa.c:70
format_t nativeformats
Definition: channel.h:852
const ast_string_field linkedid
Definition: channel.h:787
struct ast_channel * ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt,...)
Definition: channel.c:9825
struct ast_module * self
Definition: module.h:227
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:108
const ast_string_field name
Definition: channel.h:787
char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:119
char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char indevname[50]
Definition: chan_alsa.c:96
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2631
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
Definition: abstract_jb.c:616
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
format_t readformat
Definition: channel.h:853
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct ast_channel_tech * tech
Definition: channel.h:743
static int readdev
Definition: chan_alsa.c:131
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
struct ast_module * ast_module_ref(struct ast_module *)
Definition: loader.c:1300
static struct ast_frame * alsa_read ( struct ast_channel chan)
static

Definition at line 435 of file chan_alsa.c.

References ast_channel::_state, alsa, alsalock, AST_FORMAT_SLINEAR, AST_FRAME_NULL, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_STATE_UP, ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::delivery, f, FRAME_SIZE, ast_frame::frametype, chan_alsa_pvt::icard, ast_frame_subclass::integer, LOG_ERROR, ast_frame::mallocd, ast_frame::offset, ast_frame::ptr, ast_frame::samples, ast_frame::src, state, and ast_frame::subclass.

436 {
437  static struct ast_frame f;
438  static short __buf[FRAME_SIZE + AST_FRIENDLY_OFFSET / 2];
439  short *buf;
440  static int readpos = 0;
441  static int left = FRAME_SIZE;
442  snd_pcm_state_t state;
443  int r = 0;
444  int off = 0;
445 
447  f.frametype = AST_FRAME_NULL;
448  f.subclass.integer = 0;
449  f.samples = 0;
450  f.datalen = 0;
451  f.data.ptr = NULL;
452  f.offset = 0;
453  f.src = "Console";
454  f.mallocd = 0;
455  f.delivery.tv_sec = 0;
456  f.delivery.tv_usec = 0;
457 
458  if (noaudiocapture) {
459  /* Return null frame to asterisk*/
461  return &f;
462  }
463 
464  state = snd_pcm_state(alsa.icard);
465  if ((state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING)) {
466  snd_pcm_prepare(alsa.icard);
467  }
468 
469  buf = __buf + AST_FRIENDLY_OFFSET / 2;
470 
471  r = snd_pcm_readi(alsa.icard, buf + readpos, left);
472  if (r == -EPIPE) {
473 #if DEBUG
474  ast_log(LOG_ERROR, "XRUN read\n");
475 #endif
476  snd_pcm_prepare(alsa.icard);
477  } else if (r == -ESTRPIPE) {
478  ast_log(LOG_ERROR, "-ESTRPIPE\n");
479  snd_pcm_prepare(alsa.icard);
480  } else if (r < 0) {
481  ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r));
482  } else if (r >= 0) {
483  off -= r;
484  }
485 
486  /* Return NULL frame on error */
487  if (r < 0) {
489  return &f;
490  }
491 
492  /* Update positions */
493  readpos += r;
494  left -= r;
495 
496  if (readpos >= FRAME_SIZE) {
497  /* A real frame */
498  readpos = 0;
499  left = FRAME_SIZE;
500  if (chan->_state != AST_STATE_UP) {
501  /* Don't transmit unless it's up */
503  return &f;
504  }
505  if (mute) {
506  /* Don't transmit if muted */
508  return &f;
509  }
510 
511  f.frametype = AST_FRAME_VOICE;
512  f.subclass.codec = AST_FORMAT_SLINEAR;
513  f.samples = FRAME_SIZE;
514  f.datalen = FRAME_SIZE * 2;
515  f.data.ptr = buf;
516  f.offset = AST_FRIENDLY_OFFSET;
517  f.src = "Console";
518  f.mallocd = 0;
519 
520  }
522 
523  return &f;
524 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
#define FRAME_SIZE
Definition: chan_alsa.c:79
snd_pcm_t * icard
Definition: chan_alsa.c:120
static struct chan_alsa_pvt alsa
static int noaudiocapture
Definition: chan_alsa.c:136
#define ast_mutex_lock(a)
Definition: lock.h:155
static int mute
Definition: chan_alsa.c:135
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
Definition: frame.h:204
#define LOG_ERROR
Definition: logger.h:155
enum ast_channel_state _state
Definition: channel.h:839
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_format f[]
Definition: format_g726.c:181
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
Data structure associated with a single frame of data.
Definition: frame.h:142
#define ast_mutex_unlock(a)
Definition: lock.h:156
static struct ast_channel * alsa_request ( const char *  type,
format_t  format,
const struct ast_channel requestor,
void *  data,
int *  cause 
)
static

Definition at line 607 of file chan_alsa.c.

References alsa, alsa_new(), alsalock, AST_CAUSE_BUSY, AST_FORMAT_SLINEAR, ast_getformatname_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, AST_STATE_DOWN, ast_channel::linkedid, LOG_NOTICE, LOG_WARNING, and chan_alsa_pvt::owner.

608 {
609  format_t oldformat = fmt;
610  char buf[256];
611  struct ast_channel *tmp = NULL;
612 
613  if (!(fmt &= AST_FORMAT_SLINEAR)) {
614  ast_log(LOG_NOTICE, "Asked to get a channel of format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), oldformat));
615  return NULL;
616  }
617 
619 
620  if (alsa.owner) {
621  ast_log(LOG_NOTICE, "Already have a call on the ALSA channel\n");
622  *cause = AST_CAUSE_BUSY;
623  } else if (!(tmp = alsa_new(&alsa, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL))) {
624  ast_log(LOG_WARNING, "Unable to create new ALSA channel\n");
625  }
626 
628 
629  return tmp;
630 }
struct ast_channel * owner
Definition: chan_alsa.c:117
Main Channel structure associated with a channel.
Definition: channel.h:742
static struct ast_channel * alsa_new(struct chan_alsa_pvt *p, int state, const char *linkedid)
Definition: chan_alsa.c:574
static struct chan_alsa_pvt alsa
#define LOG_WARNING
Definition: logger.h:144
#define ast_mutex_lock(a)
Definition: lock.h:155
const ast_string_field linkedid
Definition: channel.h:787
int64_t format_t
Definition: frame_defs.h:32
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
#define AST_CAUSE_BUSY
Definition: causes.h:148
char * ast_getformatname_multiple(char *buf, size_t size, format_t format)
Get the names of a set of formats.
Definition: frame.c:591
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int alsa_text ( struct ast_channel c,
const char *  text 
)
static

Definition at line 301 of file chan_alsa.c.

References alsalock, ast_mutex_lock, ast_mutex_unlock, and ast_verbose().

302 {
304  ast_verbose(" << Console Received text %s >> \n", text);
306 
307  return 0;
308 }
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
#define ast_mutex_lock(a)
Definition: lock.h:155
char * text
Definition: app_queue.c:1091
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int alsa_write ( struct ast_channel chan,
struct ast_frame f 
)
static

Definition at line 383 of file chan_alsa.c.

References alsa, alsalock, ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_frame::data, ast_frame::datalen, len(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, chan_alsa_pvt::ocard, ast_frame::ptr, and state.

384 {
385  static char sizbuf[8000];
386  static int sizpos = 0;
387  int len = sizpos;
388  int res = 0;
389  /* size_t frames = 0; */
390  snd_pcm_state_t state;
391 
393 
394  /* We have to digest the frame in 160-byte portions */
395  if (f->datalen > sizeof(sizbuf) - sizpos) {
396  ast_log(LOG_WARNING, "Frame too large\n");
397  res = -1;
398  } else {
399  memcpy(sizbuf + sizpos, f->data.ptr, f->datalen);
400  len += f->datalen;
401  state = snd_pcm_state(alsa.ocard);
402  if (state == SND_PCM_STATE_XRUN)
403  snd_pcm_prepare(alsa.ocard);
404  while ((res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2)) == -EAGAIN) {
405  usleep(1);
406  }
407  if (res == -EPIPE) {
408 #if DEBUG
409  ast_debug(1, "XRUN write\n");
410 #endif
411  snd_pcm_prepare(alsa.ocard);
412  while ((res = snd_pcm_writei(alsa.ocard, sizbuf, len / 2)) == -EAGAIN) {
413  usleep(1);
414  }
415  if (res != len / 2) {
416  ast_log(LOG_ERROR, "Write error: %s\n", snd_strerror(res));
417  res = -1;
418  } else if (res < 0) {
419  ast_log(LOG_ERROR, "Write error %s\n", snd_strerror(res));
420  res = -1;
421  }
422  } else {
423  if (res == -ESTRPIPE)
424  ast_log(LOG_ERROR, "You've got some big problems\n");
425  else if (res < 0)
426  ast_log(LOG_NOTICE, "Error %d on write\n", res);
427  }
428  }
430 
431  return res >= 0 ? 0 : res;
432 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
snd_pcm_t * ocard
Definition: chan_alsa.c:120
static struct chan_alsa_pvt alsa
void * ptr
Definition: frame.h:160
#define LOG_WARNING
Definition: logger.h:144
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int datalen
Definition: frame.h:148
#define LOG_ERROR
Definition: logger.h:155
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
union ast_frame::@172 data
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* autoanswer_complete ( const char *  line,
const char *  word,
int  pos,
int  state 
)
static

Definition at line 632 of file chan_alsa.c.

References ast_strdup, ast_strlen_zero(), and MIN.

Referenced by console_autoanswer().

633 {
634  switch (state) {
635  case 0:
636  if (!ast_strlen_zero(word) && !strncasecmp(word, "on", MIN(strlen(word), 2)))
637  return ast_strdup("on");
638  case 1:
639  if (!ast_strlen_zero(word) && !strncasecmp(word, "off", MIN(strlen(word), 3)))
640  return ast_strdup("off");
641  default:
642  return NULL;
643  }
644 
645  return NULL;
646 }
#define ast_strdup(a)
Definition: astmm.h:109
Definition: ael.tab.c:203
#define MIN(a, b)
Definition: utils.h:226
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static char* console_answer ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 684 of file chan_alsa.c.

References alsa, alsalock, ast_cli_args::argc, ast_channel_unlock, ast_cli(), AST_CONTROL_ANSWER, ast_mutex_lock, ast_mutex_unlock, ast_queue_control(), ast_verbose(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, grab_owner(), chan_alsa_pvt::icard, chan_alsa_pvt::owner, and ast_cli_entry::usage.

685 {
686  char *res = CLI_SUCCESS;
687 
688  switch (cmd) {
689  case CLI_INIT:
690  e->command = "console answer";
691  e->usage =
692  "Usage: console answer\n"
693  " Answers an incoming call on the console (ALSA) channel.\n";
694 
695  return NULL;
696  case CLI_GENERATE:
697  return NULL;
698  }
699 
700  if (a->argc != 2)
701  return CLI_SHOWUSAGE;
702 
704 
705  if (!alsa.owner) {
706  ast_cli(a->fd, "No one is calling us\n");
707  res = CLI_FAILURE;
708  } else {
709  if (mute) {
710  ast_verbose( " << Muted >> \n" );
711  }
712  hookstate = 1;
713  grab_owner();
714  if (alsa.owner) {
717  }
718  }
719 
720  if (!noaudiocapture) {
721  snd_pcm_prepare(alsa.icard);
722  snd_pcm_start(alsa.icard);
723  }
724 
726 
727  return res;
728 }
struct ast_channel * owner
Definition: chan_alsa.c:117
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame with payload.
Definition: channel.c:1601
snd_pcm_t * icard
Definition: chan_alsa.c:120
static struct chan_alsa_pvt alsa
const int argc
Definition: cli.h:154
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
static int noaudiocapture
Definition: chan_alsa.c:136
Definition: cli.h:146
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static int mute
Definition: chan_alsa.c:135
const int fd
Definition: cli.h:153
#define CLI_SHOWUSAGE
Definition: cli.h:44
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static void grab_owner(void)
Definition: chan_alsa.c:310
static int hookstate
Definition: chan_alsa.c:112
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* console_autoanswer ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 648 of file chan_alsa.c.

References alsalock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_mutex_lock, ast_mutex_unlock, autoanswer_complete(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

649 {
650  char *res = CLI_SUCCESS;
651 
652  switch (cmd) {
653  case CLI_INIT:
654  e->command = "console autoanswer";
655  e->usage =
656  "Usage: console autoanswer [on|off]\n"
657  " Enables or disables autoanswer feature. If used without\n"
658  " argument, displays the current on/off status of autoanswer.\n"
659  " The default value of autoanswer is in 'alsa.conf'.\n";
660  return NULL;
661  case CLI_GENERATE:
662  return autoanswer_complete(a->line, a->word, a->pos, a->n);
663  }
664 
665  if ((a->argc != 2) && (a->argc != 3))
666  return CLI_SHOWUSAGE;
667 
669  if (a->argc == 2) {
670  ast_cli(a->fd, "Auto answer is %s.\n", autoanswer ? "on" : "off");
671  } else {
672  if (!strcasecmp(a->argv[2], "on"))
673  autoanswer = -1;
674  else if (!strcasecmp(a->argv[2], "off"))
675  autoanswer = 0;
676  else
677  res = CLI_SHOWUSAGE;
678  }
680 
681  return res;
682 }
const int argc
Definition: cli.h:154
static int autoanswer
Definition: chan_alsa.c:134
Definition: cli.h:146
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char * autoanswer_complete(const char *line, const char *word, int pos, int state)
Definition: chan_alsa.c:632
const int pos
Definition: cli.h:158
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* console_dial ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 817 of file chan_alsa.c.

References alsa, alsa_new(), alsalock, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_exists_extension(), AST_FRAME_DTMF, ast_mutex_lock, ast_mutex_unlock, ast_queue_frame(), AST_STATE_RINGING, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, context, chan_alsa_pvt::context, exten, chan_alsa_pvt::exten, ast_cli_args::fd, ast_frame::frametype, chan_alsa_pvt::owner, strsep(), and ast_cli_entry::usage.

818 {
819  char tmp[256], *tmp2;
820  char *mye, *myc;
821  const char *d;
822  char *res = CLI_SUCCESS;
823 
824  switch (cmd) {
825  case CLI_INIT:
826  e->command = "console dial";
827  e->usage =
828  "Usage: console dial [extension[@context]]\n"
829  " Dials a given extension (and context if specified)\n";
830  return NULL;
831  case CLI_GENERATE:
832  return NULL;
833  }
834 
835  if ((a->argc != 2) && (a->argc != 3))
836  return CLI_SHOWUSAGE;
837 
839 
840  if (alsa.owner) {
841  if (a->argc == 3) {
842  if (alsa.owner) {
843  for (d = a->argv[2]; *d; d++) {
844  struct ast_frame f = { .frametype = AST_FRAME_DTMF, .subclass.integer = *d };
845 
847  }
848  }
849  } else {
850  ast_cli(a->fd, "You're already in a call. You can use this only to dial digits until you hangup\n");
851  res = CLI_FAILURE;
852  }
853  } else {
854  mye = exten;
855  myc = context;
856  if (a->argc == 3) {
857  char *stringp = NULL;
858 
859  ast_copy_string(tmp, a->argv[2], sizeof(tmp));
860  stringp = tmp;
861  strsep(&stringp, "@");
862  tmp2 = strsep(&stringp, "@");
863  if (!ast_strlen_zero(tmp))
864  mye = tmp;
865  if (!ast_strlen_zero(tmp2))
866  myc = tmp2;
867  }
868  if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
869  ast_copy_string(alsa.exten, mye, sizeof(alsa.exten));
870  ast_copy_string(alsa.context, myc, sizeof(alsa.context));
871  hookstate = 1;
873  } else
874  ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc);
875  }
876 
878 
879  return res;
880 }
struct ast_channel * owner
Definition: chan_alsa.c:117
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
char * strsep(char **str, const char *delims)
static struct ast_channel * alsa_new(struct chan_alsa_pvt *p, int state, const char *linkedid)
Definition: chan_alsa.c:574
static struct chan_alsa_pvt alsa
const int argc
Definition: cli.h:154
#define AST_FRAME_DTMF
Definition: frame.h:128
Definition: cli.h:146
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:119
char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
static struct ast_format f[]
Definition: format_g726.c:181
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int hookstate
Definition: chan_alsa.c:112
Data structure associated with a single frame of data.
Definition: frame.h:142
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* console_hangup ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 779 of file chan_alsa.c.

References alsa, alsalock, ast_cli_args::argc, AST_CAUSE_NORMAL_CLEARING, ast_channel_unlock, ast_cli(), ast_mutex_lock, ast_mutex_unlock, ast_queue_hangup_with_cause(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, grab_owner(), chan_alsa_pvt::owner, and ast_cli_entry::usage.

780 {
781  char *res = CLI_SUCCESS;
782 
783  switch (cmd) {
784  case CLI_INIT:
785  e->command = "console hangup";
786  e->usage =
787  "Usage: console hangup\n"
788  " Hangs up any call currently placed on the console.\n";
789  return NULL;
790  case CLI_GENERATE:
791  return NULL;
792  }
793 
794 
795  if (a->argc != 2)
796  return CLI_SHOWUSAGE;
797 
799 
800  if (!alsa.owner && !hookstate) {
801  ast_cli(a->fd, "No call to hangup\n");
802  res = CLI_FAILURE;
803  } else {
804  hookstate = 0;
805  grab_owner();
806  if (alsa.owner) {
809  }
810  }
811 
813 
814  return res;
815 }
struct ast_channel * owner
Definition: chan_alsa.c:117
static struct chan_alsa_pvt alsa
const int argc
Definition: cli.h:154
Definition: cli.h:146
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1581
const int fd
Definition: cli.h:153
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
#define CLI_SHOWUSAGE
Definition: cli.h:44
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static void grab_owner(void)
Definition: chan_alsa.c:310
static int hookstate
Definition: chan_alsa.c:112
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* console_mute ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 882 of file chan_alsa.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

883 {
884  int toggle = 0;
885  char *res = CLI_SUCCESS;
886 
887  switch (cmd) {
888  case CLI_INIT:
889  e->command = "console {mute|unmute} [toggle]";
890  e->usage =
891  "Usage: console {mute|unmute} [toggle]\n"
892  " Mute/unmute the microphone.\n";
893  return NULL;
894  case CLI_GENERATE:
895  return NULL;
896  }
897 
898 
899  if (a->argc > 3) {
900  return CLI_SHOWUSAGE;
901  }
902 
903  if (a->argc == 3) {
904  if (strcasecmp(a->argv[2], "toggle"))
905  return CLI_SHOWUSAGE;
906  toggle = 1;
907  }
908 
909  if (a->argc < 2) {
910  return CLI_SHOWUSAGE;
911  }
912 
913  if (!strcasecmp(a->argv[1], "mute")) {
914  mute = toggle ? !mute : 1;
915  } else if (!strcasecmp(a->argv[1], "unmute")) {
916  mute = toggle ? !mute : 0;
917  } else {
918  return CLI_SHOWUSAGE;
919  }
920 
921  ast_cli(a->fd, "Console mic is %s\n", mute ? "off" : "on");
922 
923  return res;
924 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static int mute
Definition: chan_alsa.c:135
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* console_sendtext ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 730 of file chan_alsa.c.

References alsa, alsalock, ast_cli_args::argc, ast_cli_args::argv, ast_channel_unlock, ast_cli(), AST_CONTROL_ANSWER, AST_FRAME_TEXT, ast_mutex_lock, ast_mutex_unlock, ast_queue_control(), ast_queue_frame(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_frame::data, ast_frame::datalen, ast_cli_args::fd, grab_owner(), chan_alsa_pvt::owner, ast_frame::ptr, and ast_cli_entry::usage.

731 {
732  int tmparg = 3;
733  char *res = CLI_SUCCESS;
734 
735  switch (cmd) {
736  case CLI_INIT:
737  e->command = "console send text";
738  e->usage =
739  "Usage: console send text <message>\n"
740  " Sends a text message for display on the remote terminal.\n";
741  return NULL;
742  case CLI_GENERATE:
743  return NULL;
744  }
745 
746  if (a->argc < 3)
747  return CLI_SHOWUSAGE;
748 
750 
751  if (!alsa.owner) {
752  ast_cli(a->fd, "No channel active\n");
753  res = CLI_FAILURE;
754  } else {
755  struct ast_frame f = { AST_FRAME_TEXT };
756  char text2send[256] = "";
757 
758  while (tmparg < a->argc) {
759  strncat(text2send, a->argv[tmparg++], sizeof(text2send) - strlen(text2send) - 1);
760  strncat(text2send, " ", sizeof(text2send) - strlen(text2send) - 1);
761  }
762 
763  text2send[strlen(text2send) - 1] = '\n';
764  f.data.ptr = text2send;
765  f.datalen = strlen(text2send) + 1;
766  grab_owner();
767  if (alsa.owner) {
771  }
772  }
773 
775 
776  return res;
777 }
struct ast_channel * owner
Definition: chan_alsa.c:117
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame with payload.
Definition: channel.c:1601
static struct chan_alsa_pvt alsa
void * ptr
Definition: frame.h:160
const int argc
Definition: cli.h:154
Definition: cli.h:146
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const int fd
Definition: cli.h:153
int datalen
Definition: frame.h:148
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
static struct ast_format f[]
Definition: format_g726.c:181
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static void grab_owner(void)
Definition: chan_alsa.c:310
Data structure associated with a single frame of data.
Definition: frame.h:142
union ast_frame::@172 data
#define ast_mutex_unlock(a)
Definition: lock.h:156
static void grab_owner ( void  )
static

Definition at line 310 of file chan_alsa.c.

References alsa, alsalock, ast_channel_trylock, DEADLOCK_AVOIDANCE, and chan_alsa_pvt::owner.

Referenced by alsa_call(), console_answer(), console_hangup(), and console_sendtext().

311 {
312  while (alsa.owner && ast_channel_trylock(alsa.owner)) {
314  }
315 }
struct ast_channel * owner
Definition: chan_alsa.c:117
static struct chan_alsa_pvt alsa
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:485
static ast_mutex_t alsalock
Definition: chan_alsa.c:102
#define ast_channel_trylock(chan)
Definition: channel.h:2468
static int load_module ( void  )
static

Definition at line 935 of file chan_alsa.c.

References ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_jb_read_conf(), ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_true(), ast_variable_browse(), ast_verb, CONFIG_STATUS_FILEINVALID, global_jbconf, LOG_ERROR, ast_variable::name, ast_variable::next, soundcard_init(), and ast_variable::value.

936 {
937  struct ast_config *cfg;
938  struct ast_variable *v;
939  struct ast_flags config_flags = { 0 };
940 
941  /* Copy the default jb config over global_jbconf */
942  memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
943 
944  strcpy(mohinterpret, "default");
945 
946  if (!(cfg = ast_config_load(config, config_flags))) {
947  ast_log(LOG_ERROR, "Unable to read ALSA configuration file %s. Aborting.\n", config);
949  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
950  ast_log(LOG_ERROR, "%s is in an invalid format. Aborting.\n", config);
952  }
953 
954  v = ast_variable_browse(cfg, "general");
955  for (; v; v = v->next) {
956  /* handle jb conf */
957  if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) {
958  continue;
959  }
960 
961  if (!strcasecmp(v->name, "autoanswer")) {
962  autoanswer = ast_true(v->value);
963  } else if (!strcasecmp(v->name, "mute")) {
964  mute = ast_true(v->value);
965  } else if (!strcasecmp(v->name, "noaudiocapture")) {
967  } else if (!strcasecmp(v->name, "silencesuppression")) {
969  } else if (!strcasecmp(v->name, "silencethreshold")) {
970  silencethreshold = atoi(v->value);
971  } else if (!strcasecmp(v->name, "context")) {
972  ast_copy_string(context, v->value, sizeof(context));
973  } else if (!strcasecmp(v->name, "language")) {
974  ast_copy_string(language, v->value, sizeof(language));
975  } else if (!strcasecmp(v->name, "extension")) {
976  ast_copy_string(exten, v->value, sizeof(exten));
977  } else if (!strcasecmp(v->name, "input_device")) {
979  } else if (!strcasecmp(v->name, "output_device")) {
981  } else if (!strcasecmp(v->name, "mohinterpret")) {
983  }
984  }
985  ast_config_destroy(cfg);
986 
987  if (soundcard_init() < 0) {
988  ast_verb(2, "No sound card detected -- console channel will be unavailable\n");
989  ast_verb(2, "Turn off ALSA support by adding 'noload=chan_alsa.so' in /etc/asterisk/modules.conf\n");
991  }
992 
994  ast_log(LOG_ERROR, "Unable to register channel class 'Console'\n");
996  }
997 
999 
1000  return AST_MODULE_LOAD_SUCCESS;
1001 }
static char mohinterpret[MAX_MUSICCLASS]
Definition: chan_alsa.c:110
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_channel_tech alsa_tech
Definition: chan_alsa.c:149
static int silencethreshold
Definition: chan_alsa.c:100
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
Definition: abstract_jb.c:577
static struct ast_jb_conf global_jbconf
Definition: chan_alsa.c:70
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
static int noaudiocapture
Definition: chan_alsa.c:136
static int autoanswer
Definition: chan_alsa.c:134
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 ...
Definition: channel.c:907
#define ast_verb(level,...)
Definition: logger.h:243
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static int mute
Definition: chan_alsa.c:135
const char * value
Definition: config.h:79
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static int soundcard_init(void)
Definition: chan_alsa.c:271
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:108
const char * name
Definition: config.h:77
#define LOG_ERROR
Definition: logger.h:155
static char outdevname[50]
Definition: chan_alsa.c:97
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char indevname[50]
Definition: chan_alsa.c:96
static struct ast_cli_entry cli_alsa[]
Definition: chan_alsa.c:926
Structure used to handle boolean flags.
Definition: utils.h:200
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static const char config[]
Definition: chan_alsa.c:105
struct ast_variable * next
Definition: config.h:82
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
General jitterbuffer configuration.
Definition: abstract_jb.h:55
static struct ast_jb_conf default_jbconf
Definition: chan_alsa.c:63
static int silencesuppression
Definition: chan_alsa.c:99
static int soundcard_init ( void  )
static

Definition at line 271 of file chan_alsa.c.

References alsa, alsa_card_init(), ast_log(), chan_alsa_pvt::icard, LOG_ERROR, chan_alsa_pvt::ocard, and writedev.

Referenced by load_module().

272 {
273  if (!noaudiocapture) {
274  alsa.icard = alsa_card_init(indevname, SND_PCM_STREAM_CAPTURE);
275  if (!alsa.icard) {
276  ast_log(LOG_ERROR, "Problem opening alsa capture device\n");
277  return -1;
278  }
279  }
280 
281  alsa.ocard = alsa_card_init(outdevname, SND_PCM_STREAM_PLAYBACK);
282 
283  if (!alsa.ocard) {
284  ast_log(LOG_ERROR, "Problem opening ALSA playback device\n");
285  return -1;
286  }
287 
288  return writedev;
289 }
snd_pcm_t * icard
Definition: chan_alsa.c:120
snd_pcm_t * ocard
Definition: chan_alsa.c:120
static struct chan_alsa_pvt alsa
static int noaudiocapture
Definition: chan_alsa.c:136
static int writedev
Definition: chan_alsa.c:132
#define LOG_ERROR
Definition: logger.h:155
static char outdevname[50]
Definition: chan_alsa.c:97
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char indevname[50]
Definition: chan_alsa.c:96
static snd_pcm_t * alsa_card_init(char *dev, snd_pcm_stream_t stream)
Definition: chan_alsa.c:165
static int unload_module ( void  )
static

Definition at line 1003 of file chan_alsa.c.

References alsa, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, chan_alsa_pvt::icard, chan_alsa_pvt::ocard, and chan_alsa_pvt::owner.

1004 {
1007 
1008  if (alsa.icard)
1009  snd_pcm_close(alsa.icard);
1010  if (alsa.ocard)
1011  snd_pcm_close(alsa.ocard);
1012  if (alsa.owner)
1014  if (alsa.owner)
1015  return -1;
1016 
1017  return 0;
1018 }
struct ast_channel * owner
Definition: chan_alsa.c:117
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct ast_channel_tech alsa_tech
Definition: chan_alsa.c:149
snd_pcm_t * icard
Definition: chan_alsa.c:120
snd_pcm_t * ocard
Definition: chan_alsa.c:120
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
static struct chan_alsa_pvt alsa
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:938
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2746
static struct ast_cli_entry cli_alsa[]
Definition: chan_alsa.c:926

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "ALSA 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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, }
static

Definition at line 1024 of file chan_alsa.c.

struct ast_channel_tech alsa_tech
static

Definition at line 149 of file chan_alsa.c.

Referenced by alsa_new().

Definition at line 1024 of file chan_alsa.c.

int autoanswer = 1
static

Definition at line 134 of file chan_alsa.c.

struct ast_cli_entry cli_alsa[]
static

Definition at line 926 of file chan_alsa.c.

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

Definition at line 105 of file chan_alsa.c.

char context[AST_MAX_CONTEXT] = "default"
static

Definition at line 107 of file chan_alsa.c.

Referenced by __ast_goto_if_exists(), acf_isexten_exec(), acf_vmcount_exec(), action_atxfer(), action_extensionstate(), action_originate(), action_redirect(), add_peer_mailboxes(), advanced_options(), aji_mwi_cb(), append_mailbox_mapping(), apply_outgoing(), ast_async_goto(), ast_compile_ael2(), ast_event_hash_mwi(), ast_get_enum(), ast_pbx_outgoing_exten(), build_device(), build_peer(), check_access(), check_peer_ok(), complete_dialplan_add_include(), complete_dialplan_remove_extension(), complete_dialplan_remove_include(), config_parse_variables(), console_dial(), create_addr_from_peer(), disa_exec(), do_bridge_masquerade(), dundi_do_lookup(), dundi_do_precache(), dundi_do_query(), dundi_exec(), dundi_helper(), ebl_callback(), enum_callback(), extenspy_exec(), extstate_read(), feature_attended_transfer(), feature_blind_transfer(), find_label_in_current_db(), get_also_info(), get_cid_name(), get_destination(), gtalk_load_config(), handle_cli_dialplan_remove_extension(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_refer(), has_voicemail(), hint_read(), iax2_call(), iax2_transfer(), inboxcount2(), isexten_function_read(), jingle_load_config(), launch_ha_netscript(), leave_voicemail(), load_config(), local_call(), local_devicestate(), log_exec(), lua_pbx_exec(), lua_register_switches(), lua_sort_extensions(), manager_show_dialplan(), metermaidstate(), mkintf(), notify_message(), orig_exten(), pbx_builtin_background(), pbx_find_extension(), pbx_parseable_goto(), pickup_exec(), play_message(), process_ast_dsp(), pvalGotoSetTarget(), queue_mwi_event(), readexten_exec(), register_exten(), register_peer_exten(), reload_config(), retrydial_exec(), set_peer_defaults(), set_pvt_defaults(), sip_alloc(), sla_build_station(), sla_build_trunk(), socket_process(), store_config_core(), txt_callback(), unistim_send_mwi_to_peer(), unregister_exten(), update_registry(), vm_box_exists(), vmsayname_exec(), and wait_for_answer().

struct ast_jb_conf default_jbconf
static

Global jitterbuffer configuration - by default, jb is disabled

Note
Values shown here match the defaults shown in alsa.conf.sample

Definition at line 63 of file chan_alsa.c.

char exten[AST_MAX_EXTENSION] = "s"
static

Definition at line 109 of file chan_alsa.c.

Referenced by __analog_ss_thread(), __ast_goto_if_exists(), action_atxfer(), action_extensionstate(), action_originate(), action_redirect(), apply_outgoing(), ast_async_goto(), ast_compile_ael2(), ast_context_remove_extension_callerid2(), ast_ivr_menu_run_internal(), ast_merge_contexts_and_delete(), ast_pbx_outgoing_exten(), ast_walk_extension_priorities(), check_access(), check_user_full(), complete_dialplan_remove_extension(), complete_dpreply(), config_parse_variables(), console_dial(), context_used(), copy_plain_file(), create_queue_member(), disa_exec(), expand_gosub_args(), extenspy_exec(), extstate_read(), feature_attended_transfer(), feature_blind_transfer(), find_label_in_current_context(), find_label_in_current_db(), gen_prios(), get_cid_name(), get_destination(), get_rdnis(), gtalk_alloc(), handle_cli_dialplan_add_extension(), handle_cli_dialplan_remove_extension(), handle_debug_dialplan(), handle_request_invite(), handle_show_dialplan(), hint_read(), initreqprep(), isexten_function_read(), leave_voicemail(), linkprio(), local_call(), local_devicestate(), lua_pbx_exec(), lua_sort_extensions(), manager_show_dialplan(), mgcp_ss(), new_iax(), onedigit_goto(), orig_exten(), originate_exec(), osplookup_exec(), pbx_parseable_goto(), pickup_exec(), pri_ss_thread(), pvalGotoSetTarget(), raise_exception(), readexten_exec(), register_verify(), set_pvt_defaults(), sip_new(), sip_request_call(), sla_build_station(), sla_station_destructor(), socket_process(), store_config_core(), transmit_notify_with_mwi(), transmit_register(), update_scoreboard(), and waitstream_core().

struct ast_jb_conf global_jbconf
static

Definition at line 70 of file chan_alsa.c.

Referenced by alsa_new(), and load_module().

int hookstate = 0
static

Definition at line 112 of file chan_alsa.c.

char indevname[50] = ALSA_INDEV
static

Definition at line 96 of file chan_alsa.c.

int noaudiocapture = 0
static

Definition at line 136 of file chan_alsa.c.

char outdevname[50] = ALSA_OUTDEV
static

Definition at line 97 of file chan_alsa.c.

int readdev = -1
static

Definition at line 131 of file chan_alsa.c.

int silencesuppression = 0
static

Definition at line 99 of file chan_alsa.c.

int silencethreshold = 1000
static

Definition at line 100 of file chan_alsa.c.

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

Definition at line 104 of file chan_alsa.c.

int writedev = -1
static

Definition at line 132 of file chan_alsa.c.

Referenced by soundcard_init().