Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Functions | Variables
chan_console.c File Reference

Cross-platform console channel driver. More...

#include "asterisk.h"
#include <signal.h>
#include <portaudio.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/causes.h"
#include "asterisk/cli.h"
#include "asterisk/musiconhold.h"
#include "asterisk/callerid.h"
#include "asterisk/astobj2.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/format_cache.h"

Go to the source code of this file.

Data Structures

struct  console_pvt
 Console pvt structure. More...
 

Macros

#define console_pvt_lock(pvt)   ao2_lock(pvt)
 lock a console_pvt struct
 
#define console_pvt_unlock(pvt)   ao2_unlock(pvt)
 unlock a console_pvt struct
 
#define INPUT_CHANNELS   1
 Mono Input.
 
#define NUM_PVT_BUCKETS   7
 
#define NUM_SAMPLES   320
 The number of samples to configure the portaudio stream for. More...
 
#define OUTPUT_CHANNELS   1
 Mono Output.
 
#define SAMPLE_RATE   16000
 The sample rate to request from PortAudio. More...
 
#define TEXT_SIZE   256
 Maximum text message length. More...
 
#define V_BEGIN   " --- <(\"<) --- "
 Dance, Kirby, Dance!
 
#define V_END   " --- (>\")> ---\n"
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static char * ast_ext_ctx (struct console_pvt *pvt, const char *src, char **ext, char **ctx)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void build_device (struct ast_config *cfg, const char *name)
 
static char * cli_console_active (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * cli_console_answer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 answer command from the console
 
static char * cli_console_autoanswer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * cli_console_dial (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * cli_console_flash (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * cli_console_hangup (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * cli_console_mute (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * cli_console_sendtext (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Console send text CLI command. More...
 
static char * cli_list_available (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * cli_list_devices (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static struct ast_channelconsole_new (struct console_pvt *pvt, const char *ext, const char *ctx, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
 
static void destroy_pvts (void)
 
static struct console_pvtfind_pvt (const char *name)
 
static struct console_pvtget_active_pvt (void)
 
static int init_pvt (struct console_pvt *pvt, const char *name)
 
static int load_config (int reload)
 Load the configuration. More...
 
static int load_module (void)
 Load the module. More...
 
static int open_stream (struct console_pvt *pvt)
 
static int pvt_cmp_cb (void *obj, void *arg, int flags)
 
static void pvt_destructor (void *obj)
 
static int pvt_hash_cb (const void *obj, const int flags)
 
static int pvt_mark_destroy_cb (void *obj, void *arg, int flags)
 
static struct console_pvtref_pvt (struct console_pvt *pvt)
 
static int reload (void)
 
static void set_active (struct console_pvt *pvt, const char *value)
 
static void set_pvt_defaults (struct console_pvt *pvt)
 Set default values for a pvt struct. More...
 
static int start_stream (struct console_pvt *pvt)
 
static int stop_stream (struct console_pvt *pvt)
 
static void stop_streams (void)
 
static void store_callerid (struct console_pvt *pvt, const char *value)
 
static void store_config_core (struct console_pvt *pvt, const char *var, const char *value)
 Store a configuration parameter in a pvt struct. More...
 
static void * stream_monitor (void *data)
 Stream monitor thread. More...
 
static int unload_module (void)
 
static struct console_pvtunref_pvt (struct console_pvt *pvt)
 
static struct ast_channelconsole_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)
 
static int console_digit_begin (struct ast_channel *c, char digit)
 
static int console_digit_end (struct ast_channel *c, char digit, unsigned int duration)
 
static int console_text (struct ast_channel *c, const char *text)
 
static int console_hangup (struct ast_channel *c)
 
static int console_answer (struct ast_channel *c)
 
static struct ast_frameconsole_read (struct ast_channel *chan)
 Implementation of the ast_channel_tech read() callback. More...
 
static int console_call (struct ast_channel *c, const char *dest, int timeout)
 
static int console_write (struct ast_channel *chan, struct ast_frame *f)
 
static int console_indicate (struct ast_channel *chan, int cond, const void *data, size_t datalen)
 
static int console_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "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 = "da6642af068ee5e6490c5b1d2cc1d238" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, }
 
static ast_rwlock_t active_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} }
 
static struct console_pvtactive_pvt
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_console []
 
static const char config_file [] = "console.conf"
 
static struct ast_channel_tech console_tech
 
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration. More...
 
static struct ast_jb_conf global_jbconf
 
static struct console_pvt globals
 
static ast_mutex_t globals_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static struct ao2_containerpvts
 

Detailed Description

Cross-platform console channel driver.

Author
Russell Bryant russe.nosp@m.ll@d.nosp@m.igium.nosp@m..com
Note
Some of the code in this file came from chan_oss and chan_alsa. chan_oss, Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m chan_oss, Luigi Rizzo chan_alsa, Matthew Fredrickson cresl.nosp@m.in@d.nosp@m.igium.nosp@m..com

Portaudio http://www.portaudio.com/

To install portaudio v19 from svn, check it out using the following command:

Note
Since this works with any audio system that libportaudio supports, including ALSA and OSS, it has come to replace the deprecated chan_alsa and chan_oss. However, the following features at least need to be implemented here for this to be a full replacement:

Definition in file chan_console.c.

Macro Definition Documentation

#define NUM_SAMPLES   320

The number of samples to configure the portaudio stream for.

320 samples (20 ms) is the most common frame size in Asterisk. So, the code in this module reads 320 sample frames from the portaudio stream and queues them up on the Asterisk channel. Frames of any size can be written to a portaudio stream, but the portaudio documentation does say that for high performance applications, the data should be written to Pa_WriteStream in the same size as what is used to initialize the stream.

Definition at line 96 of file chan_console.c.

Referenced by stream_monitor().

#define SAMPLE_RATE   16000

The sample rate to request from PortAudio.

Todo:
Make this optional. If this is only going to talk to 8 kHz endpoints, then it makes sense to use 8 kHz natively.

Definition at line 84 of file chan_console.c.

Referenced by stream_monitor().

#define TEXT_SIZE   256

Maximum text message length.

Note
This should be changed if there is a common definition somewhere that defines the maximum length of a text message.

Definition at line 109 of file chan_console.c.

Referenced by cli_console_sendtext().

Function Documentation

static char* ast_ext_ctx ( struct console_pvt pvt,
const char *  src,
char **  ext,
char **  ctx 
)
static

split a string in extension-context, returns pointers to malloc'ed strings. If we do not have 'overridecontext' then the last @ is considered as a context separator, and the context is overridden. This is usually not very necessary as you can play with the dialplan, and it is nice not to need it because you have '@' in SIP addresses. Return value is the buffer address.

Note
came from chan_oss

Definition at line 682 of file chan_console.c.

References ast_strdup, and console_pvt::overridecontext.

683 {
684  if (ext == NULL || ctx == NULL)
685  return NULL; /* error */
686 
687  *ext = *ctx = NULL;
688 
689  if (src && *src != '\0')
690  *ext = ast_strdup(src);
691 
692  if (*ext == NULL)
693  return NULL;
694 
695  if (!pvt->overridecontext) {
696  /* parse from the right */
697  *ctx = strrchr(*ext, '@');
698  if (*ctx)
699  *(*ctx)++ = '\0';
700  }
701 
702  return *ext;
703 }
unsigned int overridecontext
Definition: chan_console.c:164
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
static char* cli_console_sendtext ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Console send text CLI command.

Note
concatenate all arguments into a single string. argv is NULL-terminated so we can use it right away

Definition at line 1121 of file chan_console.c.

References ast_cli_entry::args, AST_FRAME_TEXT, ast_join, ast_queue_frame(), ast_cli_entry::command, ast_frame::datalen, ast_frame::frametype, ast_frame::len, console_pvt::owner, TEXT_SIZE, and ast_cli_entry::usage.

1122 {
1123  char buf[TEXT_SIZE];
1124  struct console_pvt *pvt;
1125  struct ast_frame f = {
1127  .data.ptr = buf,
1128  .src = "console_send_text",
1129  };
1130  int len;
1131 
1132  if (cmd == CLI_INIT) {
1133  e->command = "console send text";
1134  e->usage =
1135  "Usage: console send text <message>\n"
1136  " Sends a text message for display on the remote terminal.\n";
1137  return NULL;
1138  } else if (cmd == CLI_GENERATE) {
1139  return NULL;
1140  }
1141 
1142  pvt = get_active_pvt();
1143  if (!pvt) {
1144  ast_cli(a->fd, "No console device is set as active\n");
1145  return CLI_FAILURE;
1146  }
1147 
1148  if (a->argc < e->args + 1) {
1149  unref_pvt(pvt);
1150  return CLI_SHOWUSAGE;
1151  }
1152 
1153  if (!pvt->owner) {
1154  ast_cli(a->fd, "Not in a call\n");
1155  unref_pvt(pvt);
1156  return CLI_FAILURE;
1157  }
1158 
1159  ast_join(buf, sizeof(buf) - 1, a->argv + e->args);
1160  if (ast_strlen_zero(buf)) {
1161  unref_pvt(pvt);
1162  return CLI_SHOWUSAGE;
1163  }
1164 
1165  len = strlen(buf);
1166  buf[len] = '\n';
1167  f.datalen = len + 1;
1168 
1169  ast_queue_frame(pvt->owner, &f);
1170 
1171  unref_pvt(pvt);
1172 
1173  return CLI_SUCCESS;
1174 }
#define ast_join(s, len, w)
Join an array of strings into a single string.
Definition: strings.h:520
struct ast_channel * owner
Definition: chan_console.c:148
int args
This gets set in ast_cli_register()
Definition: cli.h:185
Console pvt structure.
Definition: chan_console.c:124
#define TEXT_SIZE
Maximum text message length.
Definition: chan_console.c:109
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition: channel.c:1139
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
Data structure associated with a single frame of data.
enum ast_frame_type frametype
static struct ast_channel* console_new ( struct console_pvt pvt,
const char *  ext,
const char *  ctx,
int  state,
const struct ast_assigned_ids assignedids,
const struct ast_channel requestor 
)
static
Note
Called with the pvt struct locked

Definition at line 425 of file chan_console.c.

References ao2_ref, ast_channel_alloc, ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_slin16, ast_hangup(), ast_jb_configure(), ast_pbx_start(), AST_STATE_DOWN, console_pvt::cid_name, console_pvt::cid_num, console_pvt::language, console_pvt::name, and console_pvt::owner.

Referenced by console_request().

426 {
427  struct ast_format_cap *caps;
428  struct ast_channel *chan;
429 
431  if (!caps) {
432  return NULL;
433  }
434 
435  if (!(chan = ast_channel_alloc(1, state, pvt->cid_num, pvt->cid_name, NULL,
436  ext, ctx, assignedids, requestor, 0, "Console/%s", pvt->name))) {
437  ao2_ref(caps, -1);
438  return NULL;
439  }
440 
442 
443  ast_channel_tech_set(chan, &console_tech);
444  ast_channel_set_readformat(chan, ast_format_slin16);
445  ast_channel_set_writeformat(chan, ast_format_slin16);
447  ast_channel_nativeformats_set(chan, caps);
448  ao2_ref(caps, -1);
449  ast_channel_tech_pvt_set(chan, ref_pvt(pvt));
450 
451  pvt->owner = chan;
452 
453  if (!ast_strlen_zero(pvt->language))
454  ast_channel_language_set(chan, pvt->language);
455 
456  ast_jb_configure(chan, &global_jbconf);
457 
459  ast_channel_unlock(chan);
460 
461  if (state != AST_STATE_DOWN) {
462  if (ast_pbx_start(chan)) {
463  ast_channel_hangupcause_set(chan, AST_CAUSE_SWITCH_CONGESTION);
464  ast_hangup(chan);
465  chan = NULL;
466  } else
467  start_stream(pvt);
468  }
469 
470  return chan;
471 }
Main Channel structure associated with a channel.
const ast_string_field cid_num
Definition: chan_console.c:146
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4708
struct ast_channel * owner
Definition: chan_console.c:148
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
const ast_string_field language
Definition: chan_console.c:146
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
Definition: abstract_jb.c:593
struct ast_format * ast_format_slin16
Built-in cached signed linear 16kHz format.
Definition: format_cache.c:51
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1258
const ast_string_field name
Definition: chan_console.c:146
const ast_string_field cid_name
Definition: chan_console.c:146
static struct ast_frame * console_read ( struct ast_channel chan)
static

Implementation of the ast_channel_tech read() callback.

Calling this function is harmless. However, if it does get called, it is an indication that something weird happened that really shouldn't have and is worth looking into.

Why should this function not get called? Well, let me explain. There are a couple of ways to pass on audio that has come from this channel. The way that this channel driver uses is that once the audio is available, it is wrapped in an ast_frame and queued onto the channel using ast_queue_frame().

The other method would be signalling to the core that there is audio waiting, and that it needs to call the channel's read() callback to get it. The way the channel gets signalled is that one or more file descriptors are placed in the fds array on the ast_channel which the core will poll() on. When the fd indicates that input is available, the read() callback is called. This is especially useful when there is a dedicated file descriptor where the audio is read from. An example would be the socket for an RTP stream.

Definition at line 577 of file chan_console.c.

References ast_debug, and ast_null_frame.

578 {
579  ast_debug(1, "I should not be called ...\n");
580 
581  return &ast_null_frame;
582 }
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_frame ast_null_frame
Definition: main/frame.c:79
static struct ast_channel * console_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 
)
static

Channel Technology Callbacks

Definition at line 473 of file chan_console.c.

References ast_format_cap_get_names(), ast_format_cap_iscompatible(), AST_FORMAT_CAP_NAMES_LEN, AST_STATE_DOWN, ast_channel_tech::capabilities, console_new(), console_pvt_lock, console_pvt_unlock, and console_pvt::owner.

474 {
475  struct ast_channel *chan = NULL;
476  struct console_pvt *pvt;
477 
478  if (!(pvt = find_pvt(data))) {
479  ast_log(LOG_ERROR, "Console device '%s' not found\n", data);
480  return NULL;
481  }
482 
483  if (!(ast_format_cap_iscompatible(cap, console_tech.capabilities))) {
484  struct ast_str *cap_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
485  ast_log(LOG_NOTICE, "Channel requested with unsupported format(s): '%s'\n",
486  ast_format_cap_get_names(cap, &cap_buf));
487  goto return_unref;
488  }
489 
490  if (pvt->owner) {
491  ast_log(LOG_NOTICE, "Console channel already active!\n");
492  *cause = AST_CAUSE_BUSY;
493  goto return_unref;
494  }
495 
496  console_pvt_lock(pvt);
497  chan = console_new(pvt, NULL, NULL, AST_STATE_DOWN, assignedids, requestor);
498  console_pvt_unlock(pvt);
499 
500  if (!chan)
501  ast_log(LOG_WARNING, "Unable to create new Console channel!\n");
502 
503 return_unref:
504  unref_pvt(pvt);
505 
506  return chan;
507 }
Main Channel structure associated with a channel.
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
struct ast_channel * owner
Definition: chan_console.c:148
Console pvt structure.
Definition: chan_console.c:124
#define console_pvt_unlock(pvt)
unlock a console_pvt struct
Definition: chan_console.c:231
static struct ast_channel * console_new(struct console_pvt *pvt, const char *ext, const char *ctx, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
Definition: chan_console.c:425
Support for dynamic strings.
Definition: strings.h:623
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:734
struct ast_format_cap * capabilities
Definition: channel.h:632
#define console_pvt_lock(pvt)
lock a console_pvt struct
Definition: chan_console.c:228
int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if any joint capabilities exist between two capabilities structures.
Definition: format_cap.c:653
static int load_config ( int  reload)
static

Load the configuration.

Parameters
reloadif this was called due to a reload
Return values
0success
-1failure

Definition at line 1431 of file chan_console.c.

References ao2_callback, ast_category_browse(), ast_config_destroy(), ast_config_load, config_file, ast_variable::name, ast_variable::next, OBJ_NODATA, set_pvt_defaults(), store_config_core(), and ast_variable::value.

Referenced by load_module().

1432 {
1433  struct ast_config *cfg;
1434  struct ast_variable *v;
1435  struct ast_flags config_flags = { 0 };
1436  char *context = NULL;
1437 
1438  /* default values */
1439  memcpy(&global_jbconf, &default_jbconf, sizeof(global_jbconf));
1440  ast_mutex_lock(&globals_lock);
1441  set_pvt_defaults(&globals);
1442  ast_mutex_unlock(&globals_lock);
1443 
1444  if (!(cfg = ast_config_load(config_file, config_flags))) {
1445  ast_log(LOG_NOTICE, "Unable to open configuration file %s!\n", config_file);
1446  return -1;
1447  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
1448  ast_log(LOG_NOTICE, "Config file %s has an invalid format\n", config_file);
1449  return -1;
1450  }
1451 
1452  ao2_callback(pvts, OBJ_NODATA, pvt_mark_destroy_cb, NULL);
1453 
1454  ast_mutex_lock(&globals_lock);
1455  for (v = ast_variable_browse(cfg, "general"); v; v = v->next)
1456  store_config_core(&globals, v->name, v->value);
1457  ast_mutex_unlock(&globals_lock);
1458 
1459  while ((context = ast_category_browse(cfg, context))) {
1460  if (strcasecmp(context, "general"))
1461  build_device(cfg, context);
1462  }
1463 
1464  ast_config_destroy(cfg);
1465 
1466  destroy_pvts();
1467 
1468  return 0;
1469 }
struct ast_variable * next
static void set_pvt_defaults(struct console_pvt *pvt)
Set default values for a pvt struct.
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Definition: astobj2.h:1693
Structure for variables, used for configurations and for channel variables.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3326
static struct ast_jb_conf default_jbconf
Global jitterbuffer configuration.
Definition: chan_console.c:186
static const char config_file[]
#define ast_config_load(filename, flags)
Load a config file.
static void store_config_core(struct console_pvt *pvt, const char *var, const char *value)
Store a configuration parameter in a pvt struct.
Structure used to handle boolean flags.
Definition: utils.h:199
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 1528 of file chan_console.c.

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_ref, ast_channel_register(), ast_channel_unregister(), ast_cli_register_multiple, ast_cli_unregister_multiple(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_slin16, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_channel_tech::capabilities, and load_config().

1529 {
1530  PaError res;
1531 
1533  return AST_MODULE_LOAD_DECLINE;
1534  }
1536 
1537  init_pvt(&globals, NULL);
1538 
1539  pvts = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NUM_PVT_BUCKETS,
1540  pvt_hash_cb, NULL, pvt_cmp_cb);
1541  if (!pvts)
1542  goto return_error;
1543 
1544  if (load_config(0))
1545  goto return_error;
1546 
1547  res = Pa_Initialize();
1548  if (res != paNoError) {
1549  ast_log(LOG_WARNING, "Failed to initialize audio system - (%d) %s\n",
1550  res, Pa_GetErrorText(res));
1551  goto return_error_pa_init;
1552  }
1553 
1554  if (ast_channel_register(&console_tech)) {
1555  ast_log(LOG_ERROR, "Unable to register channel type 'Console'\n");
1556  goto return_error_chan_reg;
1557  }
1558 
1559  if (ast_cli_register_multiple(cli_console, ARRAY_LEN(cli_console)))
1560  goto return_error_cli_reg;
1561 
1562  return AST_MODULE_LOAD_SUCCESS;
1563 
1564 return_error_cli_reg:
1565  ast_cli_unregister_multiple(cli_console, ARRAY_LEN(cli_console));
1566 return_error_chan_reg:
1567  ast_channel_unregister(&console_tech);
1568 return_error_pa_init:
1569  Pa_Terminate();
1570 return_error:
1571  if (pvts)
1572  ao2_ref(pvts, -1);
1573  pvts = NULL;
1574  ao2_ref(console_tech.capabilities, -1);
1575  console_tech.capabilities = NULL;
1576  pvt_destructor(&globals);
1577 
1578  return AST_MODULE_LOAD_DECLINE;
1579 }
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static int load_config(int reload)
Load the configuration.
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:539
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
struct ast_format_cap * capabilities
Definition: channel.h:632
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
struct ast_format * ast_format_slin16
Built-in cached signed linear 16kHz format.
Definition: format_cache.c:51
static void set_pvt_defaults ( struct console_pvt pvt)
static

Set default values for a pvt struct.

Note
This function expects the pvt lock to be held.

Definition at line 1276 of file chan_console.c.

References ast_string_field_set, console_pvt::autoanswer, console_pvt::cid_name, console_pvt::cid_num, console_pvt::context, console_pvt::exten, console_pvt::language, console_pvt::mohinterpret, console_pvt::overridecontext, and console_pvt::parkinglot.

Referenced by load_config().

1277 {
1278  if (pvt == &globals) {
1279  ast_string_field_set(pvt, mohinterpret, "default");
1280  ast_string_field_set(pvt, context, "default");
1281  ast_string_field_set(pvt, exten, "s");
1282  ast_string_field_set(pvt, language, "");
1283  ast_string_field_set(pvt, cid_num, "");
1284  ast_string_field_set(pvt, cid_name, "");
1285  ast_string_field_set(pvt, parkinglot, "");
1286 
1287  pvt->overridecontext = 0;
1288  pvt->autoanswer = 0;
1289  } else {
1290  ast_mutex_lock(&globals_lock);
1291 
1292  ast_string_field_set(pvt, mohinterpret, globals.mohinterpret);
1293  ast_string_field_set(pvt, context, globals.context);
1294  ast_string_field_set(pvt, exten, globals.exten);
1295  ast_string_field_set(pvt, language, globals.language);
1296  ast_string_field_set(pvt, cid_num, globals.cid_num);
1297  ast_string_field_set(pvt, cid_name, globals.cid_name);
1298  ast_string_field_set(pvt, parkinglot, globals.parkinglot);
1299 
1300  pvt->overridecontext = globals.overridecontext;
1301  pvt->autoanswer = globals.autoanswer;
1302 
1303  ast_mutex_unlock(&globals_lock);
1304  }
1305 }
const ast_string_field cid_num
Definition: chan_console.c:146
const ast_string_field context
Definition: chan_console.c:146
unsigned int overridecontext
Definition: chan_console.c:164
const ast_string_field parkinglot
Definition: chan_console.c:146
unsigned int autoanswer
Definition: chan_console.c:162
const ast_string_field language
Definition: chan_console.c:146
const ast_string_field mohinterpret
Definition: chan_console.c:146
const ast_string_field cid_name
Definition: chan_console.c:146
const ast_string_field exten
Definition: chan_console.c:146
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
static void store_config_core ( struct console_pvt pvt,
const char *  var,
const char *  value 
)
static

Store a configuration parameter in a pvt struct.

Note
This function expects the pvt lock to be held.

Definition at line 1324 of file chan_console.c.

References ast_jb_read_conf(), console_pvt::autoanswer, CV_BOOL, CV_END, CV_F, CV_START, and console_pvt::overridecontext.

Referenced by load_config().

1325 {
1326  if (pvt == &globals && !ast_jb_read_conf(&global_jbconf, var, value))
1327  return;
1328 
1329  CV_START(var, value);
1330 
1331  CV_STRFIELD("context", pvt, context);
1332  CV_STRFIELD("extension", pvt, exten);
1333  CV_STRFIELD("mohinterpret", pvt, mohinterpret);
1334  CV_STRFIELD("language", pvt, language);
1335  CV_F("callerid", store_callerid(pvt, value));
1336  CV_BOOL("overridecontext", pvt->overridecontext);
1337  CV_BOOL("autoanswer", pvt->autoanswer);
1338  CV_STRFIELD("parkinglot", pvt, parkinglot);
1339 
1340  if (pvt != &globals) {
1341  CV_F("active", set_active(pvt, value))
1342  CV_STRFIELD("input_device", pvt, input_device);
1343  CV_STRFIELD("output_device", pvt, output_device);
1344  }
1345 
1346  ast_log(LOG_WARNING, "Unknown option '%s'\n", var);
1347 
1348  CV_END;
1349 }
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
Definition: abstract_jb.c:545
unsigned int overridecontext
Definition: chan_console.c:164
#define CV_END
close a variable parsing block
#define CV_START(__in_var, __in_val)
the macro to open a block for variable parsing
unsigned int autoanswer
Definition: chan_console.c:162
#define CV_F(__pattern, __body)
call a generic function if the name matches.
#define CV_BOOL(__x, __dst)
helper macros to assign the value to a BOOL, UINT, static string and dynamic string ...
static void* stream_monitor ( void *  data)
static

Stream monitor thread.

  • data A pointer to the console_pvt structure that contains the portaudio stream that needs to be monitored.

This function runs in its own thread to monitor data coming in from a portaudio stream. When enough data is available, it is queued up to be read from the Asterisk channel.

Definition at line 265 of file chan_console.c.

References console_pvt::abort, ast_debug, ast_format_slin16, AST_FRAME_VOICE, ast_queue_frame(), console_pvt_lock, console_pvt_unlock, ast_frame::frametype, INPUT_CHANNELS, console_pvt::name, NUM_SAMPLES, OUTPUT_CHANNELS, console_pvt::owner, SAMPLE_RATE, ast_frame::samples, console_pvt::stream, console_pvt::streamstate, and console_pvt::thread.

266 {
267  struct console_pvt *pvt = data;
268  char buf[NUM_SAMPLES * sizeof(int16_t)];
269  PaError res;
270  struct ast_frame f = {
272  .subclass.format = ast_format_slin16,
273  .src = "console_stream_monitor",
274  .data.ptr = buf,
275  .datalen = sizeof(buf),
276  .samples = sizeof(buf) / sizeof(int16_t),
277  };
278 
279  for (;;) {
280  console_pvt_lock(pvt);
281  res = Pa_ReadStream(pvt->stream, buf, sizeof(buf) / sizeof(int16_t));
282  console_pvt_unlock(pvt);
283 
284  if (!pvt->owner || pvt->abort) {
285  return NULL;
286  }
287 
288  if (res == paNoError) {
289  ast_queue_frame(pvt->owner, &f);
290  } else {
291  ast_log(LOG_WARNING, "Console ReadStream failed: %s\n", Pa_GetErrorText(res));
292  }
293  }
294 
295  return NULL;
296 }
unsigned int abort
Definition: chan_console.c:156
PaStream * stream
Definition: chan_console.c:150
struct ast_channel * owner
Definition: chan_console.c:148
Console pvt structure.
Definition: chan_console.c:124
#define NUM_SAMPLES
The number of samples to configure the portaudio stream for.
Definition: chan_console.c:96
#define console_pvt_unlock(pvt)
unlock a console_pvt struct
Definition: chan_console.c:231
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition: channel.c:1139
Data structure associated with a single frame of data.
struct ast_format * ast_format_slin16
Built-in cached signed linear 16kHz format.
Definition: format_cache.c:51
enum ast_frame_type frametype
#define console_pvt_lock(pvt)
lock a console_pvt struct
Definition: chan_console.c:228

Variable Documentation

struct ast_jb_conf default_jbconf
static

Global jitterbuffer configuration.

Note
Disabled by default.
Values shown here match the defaults shown in console.conf.sample

Definition at line 186 of file chan_console.c.