Asterisk - The Open Source Telephony Project GIT-master-7e7a603
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"
Include dependency graph for chan_console.c:

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 More...
 
#define console_pvt_unlock(pvt)   ao2_unlock(pvt)
 unlock a console_pvt struct More...
 
#define INPUT_CHANNELS   1
 Mono Input. More...
 
#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. More...
 
#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! More...
 
#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 More...
 
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 int console_answer (struct ast_channel *c)
 
static int console_call (struct ast_channel *c, const char *dest, int timeout)
 
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_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 
static int console_hangup (struct ast_channel *c)
 
static int console_indicate (struct ast_channel *chan, int cond, const void *data, size_t datalen)
 
static struct ast_frameconsole_read (struct ast_channel *chan)
 Implementation of the ast_channel_tech read() callback. More...
 
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_text (struct ast_channel *c, const char *text)
 
static int console_write (struct ast_channel *chan, struct ast_frame *f)
 

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 = AST_BUILDOPT_SUM, .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

◆ console_pvt_lock

#define console_pvt_lock (   pvt)    ao2_lock(pvt)

lock a console_pvt struct

Definition at line 228 of file chan_console.c.

◆ console_pvt_unlock

#define console_pvt_unlock (   pvt)    ao2_unlock(pvt)

unlock a console_pvt struct

Definition at line 231 of file chan_console.c.

◆ INPUT_CHANNELS

#define INPUT_CHANNELS   1

Mono Input.

Definition at line 99 of file chan_console.c.

◆ NUM_PVT_BUCKETS

#define NUM_PVT_BUCKETS   7

Definition at line 175 of file chan_console.c.

◆ NUM_SAMPLES

#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.

◆ OUTPUT_CHANNELS

#define OUTPUT_CHANNELS   1

Mono Output.

Definition at line 102 of file chan_console.c.

◆ SAMPLE_RATE

#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.

◆ TEXT_SIZE

#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.

◆ V_BEGIN

#define V_BEGIN   " --- <(\"<) --- "

Dance, Kirby, Dance!

Definition at line 112 of file chan_console.c.

◆ V_END

#define V_END   " --- (>\")> ---\n"

Definition at line 113 of file chan_console.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1592 of file chan_console.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1592 of file chan_console.c.

◆ ast_ext_ctx()

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.

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}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
const char * ext
Definition: http.c:150
#define NULL
Definition: resample.c:96
unsigned int overridecontext
Definition: chan_console.c:164

References ast_strdup, ext, NULL, and console_pvt::overridecontext.

Referenced by cli_console_dial().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1592 of file chan_console.c.

◆ build_device()

static void build_device ( struct ast_config cfg,
const char *  name 
)
static

Definition at line 1370 of file chan_console.c.

1371{
1372 struct ast_variable *v;
1373 struct console_pvt *pvt;
1374 int new = 0;
1375
1376 if ((pvt = find_pvt(name))) {
1377 console_pvt_lock(pvt);
1378 set_pvt_defaults(pvt);
1379 pvt->destroy = 0;
1380 } else {
1381 if (!(pvt = ao2_alloc(sizeof(*pvt), pvt_destructor)))
1382 return;
1383 init_pvt(pvt, name);
1384 set_pvt_defaults(pvt);
1385 new = 1;
1386 }
1387
1388 for (v = ast_variable_browse(cfg, name); v; v = v->next)
1389 store_config_core(pvt, v->name, v->value);
1390
1391 if (new)
1392 ao2_link(pvts, pvt);
1393 else
1394 console_pvt_unlock(pvt);
1395
1396 unref_pvt(pvt);
1397}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
#define console_pvt_lock(pvt)
lock a console_pvt struct
Definition: chan_console.c:228
static void set_pvt_defaults(struct console_pvt *pvt)
Set default values for a pvt struct.
static void pvt_destructor(void *obj)
#define console_pvt_unlock(pvt)
unlock a console_pvt struct
Definition: chan_console.c:231
static int init_pvt(struct console_pvt *pvt, const char *name)
static struct console_pvt * unref_pvt(struct console_pvt *pvt)
Definition: chan_console.c:240
static struct ao2_container * pvts
Definition: chan_console.c:174
static void store_config_core(struct console_pvt *pvt, const char *var, const char *value)
Store a configuration parameter in a pvt struct.
static struct console_pvt * find_pvt(const char *name)
Definition: chan_console.c:246
static const char name[]
Definition: format_mp3.c:68
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
Console pvt structure.
Definition: chan_console.c:124
unsigned int destroy
Definition: chan_console.c:167

References ao2_alloc, ao2_link, ast_variable_browse(), console_pvt_lock, console_pvt_unlock, console_pvt::destroy, find_pvt(), init_pvt(), name, ast_variable::name, ast_variable::next, pvt_destructor(), pvts, set_pvt_defaults(), store_config_core(), unref_pvt(), and ast_variable::value.

Referenced by load_config().

◆ cli_console_active()

static char * cli_console_active ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1193 of file chan_console.c.

1194{
1195 struct console_pvt *pvt;
1196
1197 switch (cmd) {
1198 case CLI_INIT:
1199 e->command = "console {set|show} active";
1200 e->usage =
1201 "Usage: console {set|show} active [<device>]\n"
1202 " Set or show the active console device for the Asterisk CLI.\n";
1203 return NULL;
1204 case CLI_GENERATE:
1205 if (a->pos == e->args) {
1206 struct ao2_iterator i;
1207 int x = 0;
1208 char *res = NULL;
1209 i = ao2_iterator_init(pvts, 0);
1210 while ((pvt = ao2_iterator_next(&i))) {
1211 if (++x > a->n && !strncasecmp(pvt->name, a->word, strlen(a->word)))
1212 res = ast_strdup(pvt->name);
1213 unref_pvt(pvt);
1214 if (res) {
1216 return res;
1217 }
1218 }
1220 }
1221 return NULL;
1222 }
1223
1224 if (a->argc < e->args)
1225 return CLI_SHOWUSAGE;
1226
1227 if (a->argc == 3) {
1228 pvt = get_active_pvt();
1229
1230 if (!pvt)
1231 ast_cli(a->fd, "No device is currently set as the active console device.\n");
1232 else {
1233 console_pvt_lock(pvt);
1234 ast_cli(a->fd, "The active console device is '%s'.\n", pvt->name);
1235 console_pvt_unlock(pvt);
1236 pvt = unref_pvt(pvt);
1237 }
1238
1239 return CLI_SUCCESS;
1240 }
1241
1242 if (!(pvt = find_pvt(a->argv[e->args]))) {
1243 ast_cli(a->fd, "Could not find a device called '%s'.\n", a->argv[e->args]);
1244 return CLI_FAILURE;
1245 }
1246
1247 set_active(pvt, "yes");
1248
1249 console_pvt_lock(pvt);
1250 ast_cli(a->fd, "The active console device has been set to '%s'\n", pvt->name);
1251 console_pvt_unlock(pvt);
1252
1253 unref_pvt(pvt);
1254
1255 return CLI_SUCCESS;
1256}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static void set_active(struct console_pvt *pvt, const char *value)
static struct console_pvt * get_active_pvt(void)
Definition: chan_console.c:705
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define CLI_FAILURE
Definition: cli.h:46
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
int args
This gets set in ast_cli_register()
Definition: cli.h:185
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
const ast_string_field name
Definition: chan_console.c:146
static struct test_val a

References a, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_entry::args, ast_cli(), ast_strdup, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, console_pvt_lock, console_pvt_unlock, find_pvt(), get_active_pvt(), console_pvt::name, NULL, pvts, set_active(), unref_pvt(), and ast_cli_entry::usage.

◆ cli_console_answer()

static char * cli_console_answer ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

answer command from the console

Definition at line 1071 of file chan_console.c.

1072{
1073 struct console_pvt *pvt;
1074
1075 switch (cmd) {
1076 case CLI_INIT:
1077 e->command = "console answer";
1078 e->usage =
1079 "Usage: console answer\n"
1080 " Answers an incoming call on the console channel.\n";
1081 return NULL;
1082
1083 case CLI_GENERATE:
1084 return NULL; /* no completion */
1085 }
1086
1087 pvt = get_active_pvt();
1088 if (!pvt) {
1089 ast_cli(a->fd, "No console device is set as active\n");
1090 return CLI_FAILURE;
1091 }
1092
1093 if (a->argc != e->args) {
1094 unref_pvt(pvt);
1095 return CLI_SHOWUSAGE;
1096 }
1097
1098 if (!pvt->owner) {
1099 ast_cli(a->fd, "No one is calling us\n");
1100 unref_pvt(pvt);
1101 return CLI_FAILURE;
1102 }
1103
1104 pvt->hookstate = 1;
1105
1106 ast_indicate(pvt->owner, -1);
1107
1109
1110 unref_pvt(pvt);
1111
1112 return CLI_SUCCESS;
1113}
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4277
@ AST_CONTROL_ANSWER
unsigned int hookstate
Definition: chan_console.c:158
struct ast_channel * owner
Definition: chan_console.c:148

References a, ast_cli_entry::args, ast_cli(), AST_CONTROL_ANSWER, ast_indicate(), ast_queue_control(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, get_active_pvt(), console_pvt::hookstate, NULL, console_pvt::owner, unref_pvt(), and ast_cli_entry::usage.

◆ cli_console_autoanswer()

static char * cli_console_autoanswer ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 716 of file chan_console.c.

718{
719 struct console_pvt *pvt;
720 char *res = CLI_SUCCESS;
721
722 switch (cmd) {
723 case CLI_INIT:
724 e->command = "console {set|show} autoanswer [on|off]";
725 e->usage =
726 "Usage: console {set|show} autoanswer [on|off]\n"
727 " Enables or disables autoanswer feature. If used without\n"
728 " argument, displays the current on/off status of autoanswer.\n"
729 " The default value of autoanswer is in 'oss.conf'.\n";
730 return NULL;
731
732 case CLI_GENERATE:
733 return NULL;
734 }
735
736 pvt = get_active_pvt();
737 if (!pvt) {
738 ast_cli(a->fd, "No console device is set as active.\n");
739 return CLI_FAILURE;
740 }
741
742 if (a->argc == e->args - 1) {
743 ast_cli(a->fd, "Auto answer is %s.\n", pvt->autoanswer ? "on" : "off");
744 unref_pvt(pvt);
745 return CLI_SUCCESS;
746 }
747
748 if (a->argc != e->args) {
749 unref_pvt(pvt);
750 return CLI_SHOWUSAGE;
751 }
752
753 if (!strcasecmp(a->argv[e->args-1], "on"))
754 pvt->autoanswer = 1;
755 else if (!strcasecmp(a->argv[e->args - 1], "off"))
756 pvt->autoanswer = 0;
757 else
758 res = CLI_SHOWUSAGE;
759
760 unref_pvt(pvt);
761
762 return res;
763}
unsigned int autoanswer
Definition: chan_console.c:162

References a, ast_cli_entry::args, ast_cli(), console_pvt::autoanswer, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, get_active_pvt(), NULL, unref_pvt(), and ast_cli_entry::usage.

◆ cli_console_dial()

static char * cli_console_dial ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 804 of file chan_console.c.

805{
806 char *s = NULL;
807 const char *mye = NULL, *myc = NULL;
808 struct console_pvt *pvt;
809
810 if (cmd == CLI_INIT) {
811 e->command = "console dial";
812 e->usage =
813 "Usage: console dial [extension[@context]]\n"
814 " Dials a given extension (and context if specified)\n";
815 return NULL;
816 } else if (cmd == CLI_GENERATE) {
817 return NULL;
818 }
819
820 if (a->argc > e->args + 1) {
821 return CLI_SHOWUSAGE;
822 }
823
824 pvt = get_active_pvt();
825 if (!pvt) {
826 ast_cli(a->fd, "No console device is currently set as active\n");
827 return CLI_FAILURE;
828 }
829
830 if (pvt->owner) { /* already in a call */
831 int i;
832 struct ast_frame f = { AST_FRAME_DTMF };
833 const char *s;
834
835 if (a->argc == e->args) { /* argument is mandatory here */
836 ast_cli(a->fd, "Already in a call. You can only dial digits until you hangup.\n");
837 unref_pvt(pvt);
838 return CLI_FAILURE;
839 }
840 s = a->argv[e->args];
841 /* send the string one char at a time */
842 for (i = 0; i < strlen(s); i++) {
843 f.subclass.integer = s[i];
844 ast_queue_frame(pvt->owner, &f);
845 }
846 unref_pvt(pvt);
847 return CLI_SUCCESS;
848 }
849
850 /* if we have an argument split it into extension and context */
851 if (a->argc == e->args + 1) {
852 char *ext = NULL, *con = NULL;
853 s = ast_ext_ctx(pvt, a->argv[e->args], &ext, &con);
854 mye = ext;
855 myc = con;
856 ast_debug(1, "provided '%s', exten '%s' context '%s'\n",
857 a->argv[e->args], mye, myc);
858 }
859
860 /* supply default values if needed */
861 if (ast_strlen_zero(mye))
862 mye = pvt->exten;
863 if (ast_strlen_zero(myc))
864 myc = pvt->context;
865
866 if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
867 console_pvt_lock(pvt);
868 pvt->hookstate = 1;
869 console_new(pvt, mye, myc, AST_STATE_RINGING, NULL, NULL);
871 } else
872 ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc);
873
874 ast_free(s);
875
876 unref_pvt(pvt);
877
878 return CLI_SUCCESS;
879}
#define ast_free(a)
Definition: astmm.h:180
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
static char * ast_ext_ctx(struct console_pvt *pvt, const char *src, char **ext, char **ctx)
Definition: chan_console.c:682
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
@ AST_STATE_RINGING
Definition: channelstate.h:41
#define AST_FRAME_DTMF
#define ast_debug(level,...)
Log a DEBUG message.
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:4175
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
const ast_string_field context
Definition: chan_console.c:146
const ast_string_field exten
Definition: chan_console.c:146

References a, ast_cli_entry::args, ast_cli(), ast_debug, ast_exists_extension(), ast_ext_ctx(), AST_FRAME_DTMF, ast_free, ast_queue_frame(), AST_STATE_RINGING, ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, console_new(), console_pvt_lock, console_pvt_unlock, console_pvt::context, ext, console_pvt::exten, get_active_pvt(), console_pvt::hookstate, ast_frame_subclass::integer, NULL, console_pvt::owner, ast_frame::subclass, unref_pvt(), and ast_cli_entry::usage.

◆ cli_console_flash()

static char * cli_console_flash ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 765 of file chan_console.c.

766{
767 struct console_pvt *pvt;
768
769 if (cmd == CLI_INIT) {
770 e->command = "console flash";
771 e->usage =
772 "Usage: console flash\n"
773 " Flashes the call currently placed on the console.\n";
774 return NULL;
775 } else if (cmd == CLI_GENERATE) {
776 return NULL;
777 }
778
779 if (a->argc != e->args) {
780 return CLI_SHOWUSAGE;
781 }
782
783 pvt = get_active_pvt();
784 if (!pvt) {
785 ast_cli(a->fd, "No console device is set as active\n");
786 return CLI_FAILURE;
787 }
788
789 if (!pvt->owner) {
790 ast_cli(a->fd, "No call to flash\n");
791 unref_pvt(pvt);
792 return CLI_FAILURE;
793 }
794
795 pvt->hookstate = 0;
796
798
799 unref_pvt(pvt);
800
801 return CLI_SUCCESS;
802}
@ AST_CONTROL_FLASH

References a, ast_cli_entry::args, ast_cli(), AST_CONTROL_FLASH, ast_queue_control(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, get_active_pvt(), console_pvt::hookstate, NULL, console_pvt::owner, unref_pvt(), and ast_cli_entry::usage.

◆ cli_console_hangup()

static char * cli_console_hangup ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 881 of file chan_console.c.

882{
883 struct console_pvt *pvt;
884
885 if (cmd == CLI_INIT) {
886 e->command = "console hangup";
887 e->usage =
888 "Usage: console hangup\n"
889 " Hangs up any call currently placed on the console.\n";
890 return NULL;
891 } else if (cmd == CLI_GENERATE) {
892 return NULL;
893 }
894
895 if (a->argc != e->args) {
896 return CLI_SHOWUSAGE;
897 }
898
899 pvt = get_active_pvt();
900 if (!pvt) {
901 ast_cli(a->fd, "No console device is set as active\n");
902 return CLI_FAILURE;
903 }
904
905 if (!pvt->owner && !pvt->hookstate) {
906 ast_cli(a->fd, "No call to hang up\n");
907 unref_pvt(pvt);
908 return CLI_FAILURE;
909 }
910
911 pvt->hookstate = 0;
912 if (pvt->owner)
914
915 unref_pvt(pvt);
916
917 return CLI_SUCCESS;
918}
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1150

References a, ast_cli_entry::args, ast_cli(), ast_queue_hangup(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, get_active_pvt(), console_pvt::hookstate, NULL, console_pvt::owner, unref_pvt(), and ast_cli_entry::usage.

◆ cli_console_mute()

static char * cli_console_mute ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 920 of file chan_console.c.

921{
922 const char *s;
923 struct console_pvt *pvt;
924 char *res = CLI_SUCCESS;
925
926 if (cmd == CLI_INIT) {
927 e->command = "console {mute|unmute}";
928 e->usage =
929 "Usage: console {mute|unmute}\n"
930 " Mute/unmute the microphone.\n";
931 return NULL;
932 } else if (cmd == CLI_GENERATE) {
933 return NULL;
934 }
935
936 if (a->argc != e->args) {
937 return CLI_SHOWUSAGE;
938 }
939
940 pvt = get_active_pvt();
941 if (!pvt) {
942 ast_cli(a->fd, "No console device is set as active\n");
943 return CLI_FAILURE;
944 }
945
946 s = a->argv[e->args-1];
947 if (!strcasecmp(s, "mute"))
948 pvt->muted = 1;
949 else if (!strcasecmp(s, "unmute"))
950 pvt->muted = 0;
951 else
952 res = CLI_SHOWUSAGE;
953
954 ast_verb(1, V_BEGIN "The Console is now %s" V_END,
955 pvt->muted ? "Muted" : "Unmuted");
956
957 unref_pvt(pvt);
958
959 return res;
960}
#define V_BEGIN
Dance, Kirby, Dance!
Definition: chan_console.c:112
#define V_END
Definition: chan_console.c:113
#define ast_verb(level,...)
unsigned int muted
Definition: chan_console.c:160

References a, ast_cli_entry::args, ast_cli(), ast_verb, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, get_active_pvt(), console_pvt::muted, NULL, unref_pvt(), ast_cli_entry::usage, V_BEGIN, and V_END.

◆ cli_console_sendtext()

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.

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 TEXT_SIZE
Maximum text message length.
Definition: chan_console.c:109
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
@ AST_FRAME_TEXT
#define ast_join(s, len, w)
Join an array of strings into a single string.
Definition: strings.h:520
enum ast_frame_type frametype

References a, ast_cli_entry::args, ast_cli(), AST_FRAME_TEXT, ast_join, ast_queue_frame(), ast_strlen_zero(), buf, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_frame::datalen, ast_frame::frametype, get_active_pvt(), len(), NULL, console_pvt::owner, TEXT_SIZE, unref_pvt(), and ast_cli_entry::usage.

◆ cli_list_available()

static char * cli_list_available ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 962 of file chan_console.c.

963{
964 PaDeviceIndex idx, num, def_input, def_output;
965
966 if (cmd == CLI_INIT) {
967 e->command = "console list available";
968 e->usage =
969 "Usage: console list available\n"
970 " List all available devices.\n";
971 return NULL;
972 } else if (cmd == CLI_GENERATE)
973 return NULL;
974
975 if (a->argc != e->args)
976 return CLI_SHOWUSAGE;
977
978 ast_cli(a->fd, "\n"
979 "=============================================================\n"
980 "=== Available Devices =======================================\n"
981 "=============================================================\n"
982 "===\n");
983
984 num = Pa_GetDeviceCount();
985 if (!num) {
986 ast_cli(a->fd, "(None)\n");
987 return CLI_SUCCESS;
988 }
989
990 def_input = Pa_GetDefaultInputDevice();
991 def_output = Pa_GetDefaultOutputDevice();
992 for (idx = 0; idx < num; idx++) {
993 const PaDeviceInfo *dev = Pa_GetDeviceInfo(idx);
994 if (!dev)
995 continue;
996 ast_cli(a->fd, "=== ---------------------------------------------------------\n"
997 "=== Device Name: %s\n", dev->name);
998 if (dev->maxInputChannels)
999 ast_cli(a->fd, "=== ---> %sInput Device\n", (idx == def_input) ? "Default " : "");
1000 if (dev->maxOutputChannels)
1001 ast_cli(a->fd, "=== ---> %sOutput Device\n", (idx == def_output) ? "Default " : "");
1002 ast_cli(a->fd, "=== ---------------------------------------------------------\n===\n");
1003 }
1004
1005 ast_cli(a->fd, "=============================================================\n\n");
1006
1007 return CLI_SUCCESS;
1008}
const char * name

References a, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, test_val::name, NULL, and ast_cli_entry::usage.

◆ cli_list_devices()

static char * cli_list_devices ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1010 of file chan_console.c.

1011{
1012 struct ao2_iterator i;
1013 struct console_pvt *pvt;
1014
1015 if (cmd == CLI_INIT) {
1016 e->command = "console list devices";
1017 e->usage =
1018 "Usage: console list devices\n"
1019 " List all configured devices.\n";
1020 return NULL;
1021 } else if (cmd == CLI_GENERATE)
1022 return NULL;
1023
1024 if (a->argc != e->args)
1025 return CLI_SHOWUSAGE;
1026
1027 ast_cli(a->fd, "\n"
1028 "=============================================================\n"
1029 "=== Configured Devices ======================================\n"
1030 "=============================================================\n"
1031 "===\n");
1032
1033 i = ao2_iterator_init(pvts, 0);
1034 while ((pvt = ao2_iterator_next(&i))) {
1035 console_pvt_lock(pvt);
1036
1037 ast_cli(a->fd, "=== ---------------------------------------------------------\n"
1038 "=== Device Name: %s\n"
1039 "=== ---> Active: %s\n"
1040 "=== ---> Input Device: %s\n"
1041 "=== ---> Output Device: %s\n"
1042 "=== ---> Context: %s\n"
1043 "=== ---> Extension: %s\n"
1044 "=== ---> CallerID Num: %s\n"
1045 "=== ---> CallerID Name: %s\n"
1046 "=== ---> MOH Interpret: %s\n"
1047 "=== ---> Language: %s\n"
1048 "=== ---> Parkinglot: %s\n"
1049 "=== ---> Muted: %s\n"
1050 "=== ---> Auto-Answer: %s\n"
1051 "=== ---> Override Context: %s\n"
1052 "=== ---------------------------------------------------------\n===\n",
1053 pvt->name, (pvt == active_pvt) ? "Yes" : "No",
1054 pvt->input_device, pvt->output_device, pvt->context,
1055 pvt->exten, pvt->cid_num, pvt->cid_name, pvt->mohinterpret,
1056 pvt->language, pvt->parkinglot, pvt->muted ? "Yes" : "No", pvt->autoanswer ? "Yes" : "No",
1057 pvt->overridecontext ? "Yes" : "No");
1058
1059 console_pvt_unlock(pvt);
1060 unref_pvt(pvt);
1061 }
1063
1064 ast_cli(a->fd, "=============================================================\n\n");
1065
1066 return CLI_SUCCESS;
1067}
static struct console_pvt * active_pvt
Definition: chan_console.c:177
const ast_string_field mohinterpret
Definition: chan_console.c:146
const ast_string_field language
Definition: chan_console.c:146
const ast_string_field cid_num
Definition: chan_console.c:146
const ast_string_field input_device
Definition: chan_console.c:146
const ast_string_field parkinglot
Definition: chan_console.c:146
const ast_string_field output_device
Definition: chan_console.c:146
const ast_string_field cid_name
Definition: chan_console.c:146

References a, active_pvt, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_entry::args, ast_cli(), console_pvt::autoanswer, console_pvt::cid_name, console_pvt::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, console_pvt_lock, console_pvt_unlock, console_pvt::context, console_pvt::exten, console_pvt::input_device, console_pvt::language, console_pvt::mohinterpret, console_pvt::muted, console_pvt::name, NULL, console_pvt::output_device, console_pvt::overridecontext, console_pvt::parkinglot, pvts, unref_pvt(), and ast_cli_entry::usage.

◆ console_answer()

static int console_answer ( struct ast_channel c)
static

Definition at line 546 of file chan_console.c.

547{
548 struct console_pvt *pvt = ast_channel_tech_pvt(c);
549
550 ast_verb(1, V_BEGIN "Call from Console has been Answered" V_END);
551
553
554 return start_stream(pvt);
555}
static int start_stream(struct console_pvt *pvt)
Definition: chan_console.c:359
void * ast_channel_tech_pvt(const struct ast_channel *chan)
@ AST_STATE_UP
Definition: channelstate.h:42
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7386
static struct test_val c

References ast_channel_tech_pvt(), ast_setstate(), AST_STATE_UP, ast_verb, c, start_stream(), V_BEGIN, and V_END.

◆ console_call()

static int console_call ( struct ast_channel c,
const char *  dest,
int  timeout 
)
static

Definition at line 584 of file chan_console.c.

585{
586 struct console_pvt *pvt = ast_channel_tech_pvt(c);
587 enum ast_control_frame_type ctrl;
588
589 ast_verb(1, V_BEGIN "Call to device '%s' on console from '%s' <%s>" V_END,
590 dest,
591 S_COR(ast_channel_caller(c)->id.name.valid, ast_channel_caller(c)->id.name.str, ""),
592 S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, ""));
593
594 console_pvt_lock(pvt);
595
596 if (pvt->autoanswer) {
597 pvt->hookstate = 1;
599 ast_verb(1, V_BEGIN "Auto-answered" V_END);
600 ctrl = AST_CONTROL_ANSWER;
601 } else {
603 ast_verb(1, V_BEGIN "Type 'console answer' to answer, or use the 'autoanswer' option "
604 "for future calls" V_END);
605 ctrl = AST_CONTROL_RINGING;
607 }
608
609 ast_queue_control(c, ctrl);
610
611 return start_stream(pvt);
612}
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
ast_control_frame_type
Internal control frame subtype field values.
@ AST_CONTROL_RINGING
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:87
Number structure.
Definition: app_followme.c:154

References ast_channel_caller(), ast_channel_tech_pvt(), AST_CONTROL_ANSWER, AST_CONTROL_RINGING, ast_indicate(), ast_queue_control(), ast_verb, console_pvt::autoanswer, c, console_pvt_lock, console_pvt_unlock, console_pvt::hookstate, name, S_COR, start_stream(), V_BEGIN, and V_END.

◆ console_digit_begin()

static int console_digit_begin ( struct ast_channel c,
char  digit 
)
static

Definition at line 509 of file chan_console.c.

510{
511 ast_verb(1, V_BEGIN "Console Received Beginning of Digit %c" V_END, digit);
512
513 return -1; /* non-zero to request inband audio */
514}
char digit

References ast_verb, digit, V_BEGIN, and V_END.

◆ console_digit_end()

static int console_digit_end ( struct ast_channel c,
char  digit,
unsigned int  duration 
)
static

Definition at line 516 of file chan_console.c.

517{
518 ast_verb(1, V_BEGIN "Console Received End of Digit %c (duration %u)" V_END,
519 digit, duration);
520
521 return -1; /* non-zero to request inband audio */
522}

References ast_verb, digit, V_BEGIN, and V_END.

◆ console_fixup()

static int console_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
)
static

Definition at line 662 of file chan_console.c.

663{
664 struct console_pvt *pvt = ast_channel_tech_pvt(newchan);
665
666 pvt->owner = newchan;
667
668 return 0;
669}

References ast_channel_tech_pvt(), and console_pvt::owner.

◆ console_hangup()

static int console_hangup ( struct ast_channel c)
static

Definition at line 531 of file chan_console.c.

532{
533 struct console_pvt *pvt = ast_channel_tech_pvt(c);
534
535 ast_verb(1, V_BEGIN "Hangup on Console" V_END);
536
537 pvt->hookstate = 0;
538 pvt->owner = NULL;
539 stop_stream(pvt);
540
542
543 return 0;
544}
static int stop_stream(struct console_pvt *pvt)
Definition: chan_console.c:402
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)

References ast_channel_tech_pvt(), ast_channel_tech_pvt_set(), ast_verb, c, console_pvt::hookstate, NULL, console_pvt::owner, stop_stream(), unref_pvt(), V_BEGIN, and V_END.

◆ console_indicate()

static int console_indicate ( struct ast_channel chan,
int  cond,
const void *  data,
size_t  datalen 
)
static

Definition at line 625 of file chan_console.c.

626{
627 struct console_pvt *pvt = ast_channel_tech_pvt(chan);
628 int res = 0;
629
630 switch (cond) {
631 case AST_CONTROL_BUSY:
636 case -1:
637 res = -1; /* Ask for inband indications */
638 break;
643 break;
644 case AST_CONTROL_HOLD:
645 ast_verb(1, V_BEGIN "Console Has Been Placed on Hold" V_END);
646 ast_moh_start(chan, data, pvt->mohinterpret);
647 break;
649 ast_verb(1, V_BEGIN "Console Has Been Retrieved from Hold" V_END);
650 ast_moh_stop(chan);
651 break;
652 default:
653 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n",
654 cond, ast_channel_name(chan));
655 /* The core will play inband indications for us if appropriate */
656 res = -1;
657 }
658
659 return res;
660}
ast_cond_t cond
Definition: app_sla.c:330
#define ast_log
Definition: astobj2.c:42
const char * ast_channel_name(const struct ast_channel *chan)
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_BUSY
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_PROCEEDING
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_HOLD
@ AST_CONTROL_INCOMPLETE
@ AST_CONTROL_PVT_CAUSE_CODE
#define LOG_WARNING
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:7766
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7776

References ast_channel_name(), ast_channel_tech_pvt(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log, ast_moh_start(), ast_moh_stop(), ast_verb, cond, LOG_WARNING, console_pvt::mohinterpret, V_BEGIN, and V_END.

◆ console_new()

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.

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
448 ao2_ref(caps, -1);
450
451 pvt->owner = chan;
452
453 if (!ast_strlen_zero(pvt->language))
454 ast_channel_language_set(chan, pvt->language);
455
457
459 ast_channel_unlock(chan);
460
461 if (state != AST_STATE_DOWN) {
462 if (ast_pbx_start(chan)) {
464 ast_hangup(chan);
465 chan = NULL;
466 } else
467 start_stream(pvt);
468 }
469
470 return chan;
471}
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
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define AST_CAUSE_SWITCH_CONGESTION
Definition: causes.h:123
static struct console_pvt * ref_pvt(struct console_pvt *pvt)
Definition: chan_console.c:233
static struct ast_jb_conf global_jbconf
Definition: chan_console.c:193
static struct ast_channel_tech console_tech
Definition: chan_console.c:211
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1258
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
@ AST_STATE_DOWN
Definition: channelstate.h:36
struct ast_format * ast_format_slin16
Built-in cached signed linear 16kHz format.
Definition: format_cache.c:51
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#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_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:4708
Main Channel structure associated with a channel.
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54

References ao2_ref, AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc, ast_channel_hangupcause_set(), ast_channel_nativeformats_set(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_tech_pvt_set(), ast_channel_tech_set(), ast_channel_unlock, 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, ast_strlen_zero(), console_pvt::cid_name, console_pvt::cid_num, console_tech, ext, global_jbconf, console_pvt::language, console_pvt::name, NULL, console_pvt::owner, ref_pvt(), and start_stream().

Referenced by cli_console_dial(), and console_request().

◆ console_read()

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.

578{
579 ast_debug(1, "I should not be called ...\n");
580
581 return &ast_null_frame;
582}
struct ast_frame ast_null_frame
Definition: main/frame.c:79

References ast_debug, and ast_null_frame.

◆ console_request()

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.

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
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);
499
500 if (!chan)
501 ast_log(LOG_WARNING, "Unable to create new Console channel!\n");
502
503return_unref:
504 unref_pvt(pvt);
505
506 return chan;
507}
#define AST_CAUSE_BUSY
Definition: causes.h:149
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
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
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
#define LOG_ERROR
#define LOG_NOTICE
#define ast_str_alloca(init_len)
Definition: strings.h:848
struct ast_format_cap * capabilities
Definition: channel.h:632
Support for dynamic strings.
Definition: strings.h:623

References AST_CAUSE_BUSY, ast_format_cap_get_names(), ast_format_cap_iscompatible(), AST_FORMAT_CAP_NAMES_LEN, ast_log, AST_STATE_DOWN, ast_str_alloca, ast_channel_tech::capabilities, console_new(), console_pvt_lock, console_pvt_unlock, console_tech, find_pvt(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, NULL, console_pvt::owner, and unref_pvt().

◆ console_text()

static int console_text ( struct ast_channel c,
const char *  text 
)
static

Definition at line 524 of file chan_console.c.

525{
526 ast_verb(1, V_BEGIN "Console Received Text '%s'" V_END, text);
527
528 return 0;
529}
char * text
Definition: app_queue.c:1639

References ast_verb, text, V_BEGIN, and V_END.

◆ console_write()

static int console_write ( struct ast_channel chan,
struct ast_frame f 
)
static

Definition at line 614 of file chan_console.c.

615{
616 struct console_pvt *pvt = ast_channel_tech_pvt(chan);
617
618 console_pvt_lock(pvt);
619 Pa_WriteStream(pvt->stream, f->data.ptr, f->samples);
621
622 return 0;
623}
union ast_frame::@226 data
PaStream * stream
Definition: chan_console.c:150

References ast_channel_tech_pvt(), console_pvt_lock, console_pvt_unlock, ast_frame::data, ast_frame::ptr, ast_frame::samples, and console_pvt::stream.

◆ destroy_pvts()

static void destroy_pvts ( void  )
static

Definition at line 1406 of file chan_console.c.

1407{
1408 struct ao2_iterator i;
1409 struct console_pvt *pvt;
1410
1411 i = ao2_iterator_init(pvts, 0);
1412 while ((pvt = ao2_iterator_next(&i))) {
1413 if (pvt->destroy) {
1414 ao2_unlink(pvts, pvt);
1416 if (active_pvt == pvt)
1417 active_pvt = unref_pvt(pvt);
1419 }
1420 unref_pvt(pvt);
1421 }
1423}
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578
static ast_rwlock_t active_lock
Definition: chan_console.c:178
#define ast_rwlock_wrlock(a)
Definition: lock.h:236
#define ast_rwlock_unlock(a)
Definition: lock.h:234

References active_lock, active_pvt, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_unlink, ast_rwlock_unlock, ast_rwlock_wrlock, console_pvt::destroy, pvts, and unref_pvt().

Referenced by load_config().

◆ find_pvt()

static struct console_pvt * find_pvt ( const char *  name)
static

Definition at line 246 of file chan_console.c.

247{
248 struct console_pvt tmp_pvt = {
249 .name = name,
250 };
251
252 return ao2_find(pvts, &tmp_pvt, OBJ_POINTER);
253}
#define OBJ_POINTER
Definition: astobj2.h:1150
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736

References ao2_find, name, console_pvt::name, OBJ_POINTER, and pvts.

Referenced by build_device(), cli_console_active(), and console_request().

◆ get_active_pvt()

static struct console_pvt * get_active_pvt ( void  )
static

◆ init_pvt()

static int init_pvt ( struct console_pvt pvt,
const char *  name 
)
static

Definition at line 1358 of file chan_console.c.

1359{
1361
1362 if (ast_string_field_init(pvt, 32))
1363 return -1;
1364
1365 ast_string_field_set(pvt, name, S_OR(name, ""));
1366
1367 return 0;
1368}
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
pthread_t thread
Definition: chan_console.c:169

References AST_PTHREADT_NULL, ast_string_field_init, ast_string_field_set, name, S_OR, and console_pvt::thread.

Referenced by build_device(), and load_module().

◆ load_config()

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.

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));
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
1453
1455 for (v = ast_variable_browse(cfg, "general"); v; v = v->next)
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}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
@ OBJ_NODATA
Definition: astobj2.h:1044
static void build_device(struct ast_config *cfg, const char *name)
static void destroy_pvts(void)
static struct ast_jb_conf default_jbconf
Global jitterbuffer configuration.
Definition: chan_console.c:186
static const char config_file[]
Definition: chan_console.c:116
static struct console_pvt globals
static ast_mutex_t globals_lock
Definition: chan_console.c:172
static int pvt_mark_destroy_cb(void *obj, void *arg, int flags)
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3326
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_lock(a)
Definition: lock.h:189
Structure used to handle boolean flags.
Definition: utils.h:199

References ao2_callback, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_variable_browse(), build_device(), config_file, CONFIG_STATUS_FILEINVALID, voicemailpwcheck::context, default_jbconf, destroy_pvts(), global_jbconf, globals, globals_lock, LOG_NOTICE, ast_variable::name, ast_variable::next, NULL, OBJ_NODATA, pvt_mark_destroy_cb(), pvts, set_pvt_defaults(), store_config_core(), and ast_variable::value.

Referenced by load_module(), and reload().

◆ load_module()

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.

1529{
1530 PaError res;
1531
1534 }
1536
1538
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
1555 ast_log(LOG_ERROR, "Unable to register channel type 'Console'\n");
1556 goto return_error_chan_reg;
1557 }
1558
1560 goto return_error_cli_reg;
1561
1563
1564return_error_cli_reg:
1566return_error_chan_reg:
1568return_error_pa_init:
1569 Pa_Terminate();
1570return_error:
1571 if (pvts)
1572 ao2_ref(pvts, -1);
1573 pvts = NULL;
1577
1579}
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#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
#define NUM_PVT_BUCKETS
Definition: chan_console.c:175
static int pvt_hash_cb(const void *obj, const int flags)
static int pvt_cmp_cb(void *obj, void *arg, int flags)
static struct ast_cli_entry cli_console[]
static int load_config(int reload)
Load the configuration.
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
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
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ARRAY_LEN(a)
Definition: utils.h:666

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ao2_ref, ARRAY_LEN, 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_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_channel_tech::capabilities, cli_console, console_tech, globals, init_pvt(), load_config(), LOG_ERROR, LOG_WARNING, NULL, NUM_PVT_BUCKETS, pvt_cmp_cb(), pvt_destructor(), pvt_hash_cb(), and pvts.

◆ open_stream()

static int open_stream ( struct console_pvt pvt)
static

Definition at line 298 of file chan_console.c.

299{
300 int res = paInternalError;
301
302 if (!strcasecmp(pvt->input_device, "default") &&
303 !strcasecmp(pvt->output_device, "default")) {
304 res = Pa_OpenDefaultStream(&pvt->stream, INPUT_CHANNELS, OUTPUT_CHANNELS,
305 paInt16, SAMPLE_RATE, NUM_SAMPLES, NULL, NULL);
306 } else {
307 PaStreamParameters input_params = {
308 .channelCount = 1,
309 .sampleFormat = paInt16,
310 .suggestedLatency = (1.0 / 50.0), /* 20 ms */
311 .device = paNoDevice,
312 };
313 PaStreamParameters output_params = {
314 .channelCount = 1,
315 .sampleFormat = paInt16,
316 .suggestedLatency = (1.0 / 50.0), /* 20 ms */
317 .device = paNoDevice,
318 };
319 PaDeviceIndex idx, num_devices, def_input, def_output;
320
321 if (!(num_devices = Pa_GetDeviceCount()))
322 return res;
323
324 def_input = Pa_GetDefaultInputDevice();
325 def_output = Pa_GetDefaultOutputDevice();
326
327 for (idx = 0;
328 idx < num_devices && (input_params.device == paNoDevice
329 || output_params.device == paNoDevice);
330 idx++)
331 {
332 const PaDeviceInfo *dev = Pa_GetDeviceInfo(idx);
333
334 if (dev->maxInputChannels) {
335 if ( (idx == def_input && !strcasecmp(pvt->input_device, "default")) ||
336 !strcasecmp(pvt->input_device, dev->name) )
337 input_params.device = idx;
338 }
339
340 if (dev->maxOutputChannels) {
341 if ( (idx == def_output && !strcasecmp(pvt->output_device, "default")) ||
342 !strcasecmp(pvt->output_device, dev->name) )
343 output_params.device = idx;
344 }
345 }
346
347 if (input_params.device == paNoDevice)
348 ast_log(LOG_ERROR, "No input device found for console device '%s'\n", pvt->name);
349 if (output_params.device == paNoDevice)
350 ast_log(LOG_ERROR, "No output device found for console device '%s'\n", pvt->name);
351
352 res = Pa_OpenStream(&pvt->stream, &input_params, &output_params,
353 SAMPLE_RATE, NUM_SAMPLES, paNoFlag, NULL, NULL);
354 }
355
356 return res;
357}
#define SAMPLE_RATE
The sample rate to request from PortAudio.
Definition: chan_console.c:84
#define OUTPUT_CHANNELS
Mono Output.
Definition: chan_console.c:102
#define INPUT_CHANNELS
Mono Input.
Definition: chan_console.c:99
#define NUM_SAMPLES
The number of samples to configure the portaudio stream for.
Definition: chan_console.c:96

References ast_log, INPUT_CHANNELS, console_pvt::input_device, LOG_ERROR, console_pvt::name, NULL, NUM_SAMPLES, OUTPUT_CHANNELS, console_pvt::output_device, SAMPLE_RATE, and console_pvt::stream.

Referenced by start_stream().

◆ pvt_cmp_cb()

static int pvt_cmp_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1478 of file chan_console.c.

1479{
1480 struct console_pvt *pvt = obj, *pvt2 = arg;
1481
1482 return !strcasecmp(pvt->name, pvt2->name) ? CMP_MATCH | CMP_STOP : 0;
1483}
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028

References CMP_MATCH, CMP_STOP, and console_pvt::name.

Referenced by load_module().

◆ pvt_destructor()

static void pvt_destructor ( void *  obj)
static

Definition at line 1351 of file chan_console.c.

1352{
1353 struct console_pvt *pvt = obj;
1354
1356}
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

References ast_string_field_free_memory.

Referenced by build_device(), load_module(), and unload_module().

◆ pvt_hash_cb()

static int pvt_hash_cb ( const void *  obj,
const int  flags 
)
static

Definition at line 1471 of file chan_console.c.

1472{
1473 const struct console_pvt *pvt = obj;
1474
1475 return ast_str_case_hash(pvt->name);
1476}
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1303

References ast_str_case_hash(), and console_pvt::name.

Referenced by load_module().

◆ pvt_mark_destroy_cb()

static int pvt_mark_destroy_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1399 of file chan_console.c.

1400{
1401 struct console_pvt *pvt = obj;
1402 pvt->destroy = 1;
1403 return 0;
1404}

References console_pvt::destroy.

Referenced by load_config().

◆ ref_pvt()

static struct console_pvt * ref_pvt ( struct console_pvt pvt)
inlinestatic

Definition at line 233 of file chan_console.c.

234{
235 if (pvt)
236 ao2_ref(pvt, +1);
237 return pvt;
238}

References ao2_ref.

Referenced by console_new(), get_active_pvt(), and set_active().

◆ reload()

static int reload ( void  )
static

Definition at line 1581 of file chan_console.c.

1582{
1583 return load_config(1);
1584}

References load_config().

◆ set_active()

static void set_active ( struct console_pvt pvt,
const char *  value 
)
static

Definition at line 1176 of file chan_console.c.

1177{
1178 if (pvt == &globals) {
1179 ast_log(LOG_ERROR, "active is only valid as a per-device setting\n");
1180 return;
1181 }
1182
1183 if (!ast_true(value))
1184 return;
1185
1187 if (active_pvt)
1189 active_pvt = ref_pvt(pvt);
1191}
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
int value
Definition: syslog.c:37

References active_lock, active_pvt, ast_log, ast_rwlock_unlock, ast_rwlock_wrlock, ast_true(), globals, LOG_ERROR, ref_pvt(), unref_pvt(), and value.

Referenced by cli_console_active(), and store_config_core().

◆ set_pvt_defaults()

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.

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");
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 {
1291
1294 ast_string_field_set(pvt, exten, globals.exten);
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
1302
1304 }
1305}
static char language[MAX_LANGUAGE]
Definition: chan_iax2.c:324
static char mohinterpret[MAX_MUSICCLASS]
Definition: chan_iax2.c:474

References ast_mutex_lock, ast_mutex_unlock, ast_string_field_set, console_pvt::autoanswer, console_pvt::cid_name, console_pvt::cid_num, console_pvt::context, voicemailpwcheck::context, console_pvt::exten, globals, globals_lock, console_pvt::language, language, console_pvt::mohinterpret, mohinterpret, console_pvt::overridecontext, and console_pvt::parkinglot.

Referenced by build_device(), and load_config().

◆ start_stream()

static int start_stream ( struct console_pvt pvt)
static

Definition at line 359 of file chan_console.c.

360{
361 PaError res;
362 int ret_val = 0;
363
364 console_pvt_lock(pvt);
365
366 /* It is possible for console_hangup to be called before the
367 * stream is started, if this is the case pvt->owner will be NULL
368 * and start_stream should be aborted. */
369 if (pvt->streamstate || !pvt->owner)
370 goto return_unlock;
371
372 pvt->streamstate = 1;
373 ast_debug(1, "Starting stream\n");
374
375 res = open_stream(pvt);
376 if (res != paNoError) {
377 ast_log(LOG_WARNING, "Failed to open stream - (%d) %s\n",
378 res, Pa_GetErrorText(res));
379 ret_val = -1;
380 goto return_unlock;
381 }
382
383 res = Pa_StartStream(pvt->stream);
384 if (res != paNoError) {
385 ast_log(LOG_WARNING, "Failed to start stream - (%d) %s\n",
386 res, Pa_GetErrorText(res));
387 ret_val = -1;
388 goto return_unlock;
389 }
390
392 ast_log(LOG_ERROR, "Failed to start stream monitor thread\n");
393 ret_val = -1;
394 }
395
396return_unlock:
398
399 return ret_val;
400}
static int open_stream(struct console_pvt *pvt)
Definition: chan_console.c:298
static void * stream_monitor(void *data)
Stream monitor thread.
Definition: chan_console.c:265
unsigned int streamstate
Definition: chan_console.c:154
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:592

References ast_debug, ast_log, ast_pthread_create_background, console_pvt_lock, console_pvt_unlock, LOG_ERROR, LOG_WARNING, NULL, open_stream(), console_pvt::owner, console_pvt::stream, stream_monitor(), console_pvt::streamstate, and console_pvt::thread.

Referenced by console_answer(), console_call(), and console_new().

◆ stop_stream()

static int stop_stream ( struct console_pvt pvt)
static

Definition at line 402 of file chan_console.c.

403{
404 if (!pvt->streamstate || pvt->thread == AST_PTHREADT_NULL)
405 return 0;
406
407 pvt->abort = 1;
408 /* Wait for pvt->thread to exit cleanly, to avoid killing it while it's holding a lock. */
409 pthread_kill(pvt->thread, SIGURG); /* Wake it up if needed, but don't cancel it */
410 pthread_join(pvt->thread, NULL);
411
412 console_pvt_lock(pvt);
413 Pa_AbortStream(pvt->stream);
414 Pa_CloseStream(pvt->stream);
415 pvt->stream = NULL;
416 pvt->streamstate = 0;
418
419 return 0;
420}
unsigned int abort
Definition: chan_console.c:156

References console_pvt::abort, AST_PTHREADT_NULL, console_pvt_lock, console_pvt_unlock, NULL, console_pvt::stream, console_pvt::streamstate, and console_pvt::thread.

Referenced by console_hangup(), and stop_streams().

◆ stop_streams()

static void stop_streams ( void  )
static

Definition at line 1485 of file chan_console.c.

1486{
1487 struct console_pvt *pvt;
1488 struct ao2_iterator i;
1489
1490 i = ao2_iterator_init(pvts, 0);
1491 while ((pvt = ao2_iterator_next(&i))) {
1492 if (pvt->hookstate)
1493 stop_stream(pvt);
1494 unref_pvt(pvt);
1495 }
1497}

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, console_pvt::hookstate, pvts, stop_stream(), and unref_pvt().

Referenced by unload_module().

◆ store_callerid()

static void store_callerid ( struct console_pvt pvt,
const char *  value 
)
static

Definition at line 1307 of file chan_console.c.

1308{
1309 char cid_name[256];
1310 char cid_num[256];
1311
1312 ast_callerid_split(value, cid_name, sizeof(cid_name),
1313 cid_num, sizeof(cid_num));
1314
1315 ast_string_field_set(pvt, cid_name, cid_name);
1316 ast_string_field_set(pvt, cid_num, cid_num);
1317}
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1292

References ast_callerid_split(), ast_string_field_set, and value.

Referenced by store_config_core().

◆ store_config_core()

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.

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
#define var
Definition: ast_expr2f.c:605
static void store_callerid(struct console_pvt *pvt, const char *value)
#define CV_START(__in_var, __in_val)
the macro to open a block for variable parsing
#define CV_STRFIELD(__x, __obj, __field)
#define CV_END
close a variable parsing block
#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

References ast_jb_read_conf(), ast_log, console_pvt::autoanswer, voicemailpwcheck::context, CV_BOOL, CV_END, CV_F, CV_START, CV_STRFIELD, global_jbconf, globals, language, LOG_WARNING, mohinterpret, console_pvt::overridecontext, set_active(), store_callerid(), value, and var.

Referenced by build_device(), and load_config().

◆ stream_monitor()

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.

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));
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}
short int16_t
Definition: db.h:59
@ AST_FRAME_VOICE

References console_pvt::abort, ast_format_slin16, AST_FRAME_VOICE, ast_log, ast_queue_frame(), buf, console_pvt_lock, console_pvt_unlock, ast_frame::frametype, LOG_WARNING, NULL, NUM_SAMPLES, console_pvt::owner, ast_frame::samples, and console_pvt::stream.

Referenced by start_stream().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1499 of file chan_console.c.

1500{
1505
1506 stop_streams();
1507
1508 Pa_Terminate();
1509
1510 /* Will unref all the pvts so they will get destroyed, too */
1511 ao2_ref(pvts, -1);
1512
1514
1515 return 0;
1516}
static void stop_streams(void)

References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_channel_tech::capabilities, cli_console, console_tech, globals, NULL, pvt_destructor(), pvts, and stop_streams().

◆ unref_pvt()

static struct console_pvt * unref_pvt ( struct console_pvt pvt)
inlinestatic

Variable Documentation

◆ __mod_info

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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, }
static

Definition at line 1592 of file chan_console.c.

◆ active_lock

ast_rwlock_t active_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} }
static

Definition at line 178 of file chan_console.c.

Referenced by destroy_pvts(), get_active_pvt(), and set_active().

◆ active_pvt

struct console_pvt* active_pvt
static

Definition at line 177 of file chan_console.c.

Referenced by cli_list_devices(), destroy_pvts(), get_active_pvt(), and set_active().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1592 of file chan_console.c.

◆ cli_console

struct ast_cli_entry cli_console[]
static

Definition at line 1258 of file chan_console.c.

Referenced by load_module(), and unload_module().

◆ config_file

const char config_file[] = "console.conf"
static

Definition at line 116 of file chan_console.c.

Referenced by load_config().

◆ console_tech

struct ast_channel_tech console_tech
static

Definition at line 211 of file chan_console.c.

Referenced by console_new(), console_request(), load_module(), and unload_module().

◆ default_jbconf

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.

Referenced by load_config().

◆ global_jbconf

struct ast_jb_conf global_jbconf
static

Definition at line 193 of file chan_console.c.

Referenced by console_new(), load_config(), and store_config_core().

◆ globals

struct console_pvt globals
static
Examples
app_skel.c.

Referenced by __ast_udptl_reload(), acf_jabberreceive_read(), acf_jabberstatus_read(), app_exec(), ast_get_builtin_feature(), ast_get_chan_applicationmap(), ast_get_chan_featuremap_config(), ast_get_chan_features_general_config(), ast_get_chan_features_pickup_config(), ast_get_chan_features_xfer_config(), ast_named_acl_find(), ast_udptl_new_with_bindaddr(), ast_xmpp_client_find(), cli_complete_notify(), cli_display_named_acl(), cli_display_named_acl_list(), cli_notify(), delete_old_messages(), generate_or_link_lots_to_configs(), get_feature_ds(), global_loaded_observer(), handle_cli_show_config(), handle_feature_show(), handle_show_named_acl_cmd(), handle_skel_show_config(), handle_skel_show_levels(), jingle_endpoint_state_find_or_create(), jingle_request(), load_config(), load_module(), manager_jabber_send(), manager_notify_endpoint(), manager_notify_uri(), parking_dynamic_lots_enabled(), remove_all_configured_parking_lot_extensions(), set_active(), set_pvt_defaults(), skel_find_or_create_state(), stasis_cleanup(), stasis_init(), stasis_message_type_declined(), store_config_core(), unbound_config_apply_default(), unbound_resolver_resolve(), unload_features_config(), unload_module(), xmpp_action_hook(), xmpp_cli_create_collection(), xmpp_cli_create_leafnode(), xmpp_cli_delete_pubsub_node(), xmpp_cli_list_pubsub_nodes(), xmpp_cli_purge_pubsub_nodes(), xmpp_client_config_post_apply(), xmpp_client_find_or_create(), xmpp_client_reconnect(), xmpp_client_send_message(), xmpp_client_set_group_presence(), xmpp_client_set_presence(), xmpp_client_thread(), xmpp_component_register_get_hook(), xmpp_component_service_discovery_get_hook(), xmpp_component_service_discovery_items_hook(), xmpp_config_post_apply(), xmpp_config_prelink(), xmpp_connect_hook(), xmpp_init_event_distribution(), xmpp_join_exec(), xmpp_leave_exec(), xmpp_log_hook(), xmpp_pubsub_build_publish_skeleton(), xmpp_pubsub_handle_error(), xmpp_pubsub_iq_create(), xmpp_pubsub_publish_device_state(), xmpp_pubsub_subscribe(), xmpp_roster_hook(), xmpp_send_cb(), xmpp_send_exec(), xmpp_sendgroup_exec(), xmpp_show_buddies(), and xmpp_show_clients().

◆ globals_lock

ast_mutex_t globals_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 172 of file chan_console.c.

Referenced by load_config(), and set_pvt_defaults().

◆ pvts

struct ao2_container* pvts
static