59 #include <sys/signal.h>
61 #include <portaudio.h>
78 #define SAMPLE_RATE 16000
90 #define NUM_SAMPLES 320
93 #define INPUT_CHANNELS 1
96 #define OUTPUT_CHANNELS 1
103 #define TEXT_SIZE 256
106 #define V_BEGIN " --- <(\"<) --- "
107 #define V_END " --- (>\")> ---\n"
167 #define NUM_PVT_BUCKETS 7
181 .resync_threshold = 1000,
206 #define SUPPORTED_FORMATS ( AST_FORMAT_SLINEAR16 )
210 .description =
"Console Channel Driver",
226 #define console_pvt_lock(pvt) ao2_lock(pvt)
229 #define console_pvt_unlock(pvt) ao2_unlock(pvt)
271 .src =
"console_stream_monitor",
273 .datalen =
sizeof(buf),
274 .
samples =
sizeof(buf) /
sizeof(int16_t),
278 pthread_testcancel();
279 res = Pa_ReadStream(pvt->
stream, buf,
sizeof(buf) /
sizeof(int16_t));
280 pthread_testcancel();
286 if (res == paNoError)
295 int res = paInternalError;
302 PaStreamParameters input_params = {
304 .sampleFormat = paInt16,
305 .suggestedLatency = (1.0 / 50.0),
306 .device = paNoDevice,
308 PaStreamParameters output_params = {
310 .sampleFormat = paInt16,
311 .suggestedLatency = (1.0 / 50.0),
312 .device = paNoDevice,
314 PaDeviceIndex idx, num_devices, def_input, def_output;
316 if (!(num_devices = Pa_GetDeviceCount()))
319 def_input = Pa_GetDefaultInputDevice();
320 def_output = Pa_GetDefaultOutputDevice();
323 idx < num_devices && (input_params.device == paNoDevice
324 || output_params.device == paNoDevice);
327 const PaDeviceInfo *dev = Pa_GetDeviceInfo(idx);
329 if (dev->maxInputChannels) {
330 if ( (idx == def_input && !strcasecmp(pvt->
input_device,
"default")) ||
332 input_params.device = idx;
335 if (dev->maxOutputChannels) {
336 if ( (idx == def_output && !strcasecmp(pvt->
output_device,
"default")) ||
338 output_params.device = idx;
342 if (input_params.device == paNoDevice)
344 if (output_params.device == paNoDevice)
347 res = Pa_OpenStream(&pvt->
stream, &input_params, &output_params,
371 if (res != paNoError) {
373 res, Pa_GetErrorText(res));
378 res = Pa_StartStream(pvt->
stream);
379 if (res != paNoError) {
381 res, Pa_GetErrorText(res));
402 pthread_cancel(pvt->
thread);
403 pthread_kill(pvt->
thread, SIGURG);
404 pthread_join(pvt->
thread, NULL);
407 Pa_AbortStream(pvt->
stream);
408 Pa_CloseStream(pvt->
stream);
424 ext, ctx, linkedid, 0,
"Console/%s", pvt->
name))) {
560 ast_debug(1,
"I should not be called ...\n");
584 ast_verb(1,
V_BEGIN "Type 'console answer' to answer, or use the 'autoanswer' option "
585 "for future calls" V_END);
644 pvt->
owner = newchan;
662 if (ext == NULL || ctx == NULL)
667 if (src && *src !=
'\0')
675 *ctx = strrchr(*ext,
'@');
702 e->
command =
"console {set|show} autoanswer [on|off]";
704 "Usage: console {set|show} autoanswer [on|off]\n"
705 " Enables or disables autoanswer feature. If used without\n"
706 " argument, displays the current on/off status of autoanswer.\n"
707 " The default value of autoanswer is in 'oss.conf'.\n";
715 ast_cli(a->
fd,
"No console device is set as active.\n");
730 if (!strcasecmp(a->
argv[e->
args-1],
"on"))
732 else if (!strcasecmp(a->
argv[e->
args - 1],
"off"))
749 "Usage: console flash\n"
750 " Flashes the call currently placed on the console.\n";
756 ast_cli(a->
fd,
"No console device is set as active\n");
781 const char *mye = NULL, *myc = NULL;
787 "Usage: console dial [extension[@context]]\n"
788 " Dials a given extension (and context if specified)\n";
794 ast_cli(a->
fd,
"No console device is currently set as active\n");
807 ast_cli(a->
fd,
"Already in a call. You can only dial digits until you hangup.\n");
813 for (i = 0; i < strlen(s); i++) {
823 char *
ext = NULL, *con = NULL;
825 ast_debug(1,
"provided '%s', exten '%s' context '%s'\n",
843 ast_cli(a->
fd,
"No such extension '%s' in context '%s'\n", mye, myc);
859 "Usage: console hangup\n"
860 " Hangs up any call currently placed on the console.\n";
866 ast_cli(a->
fd,
"No console device is set as active\n");
895 e->
command =
"console {mute|unmute}";
897 "Usage: console {mute|unmute}\n"
898 " Mute/unmute the microphone.\n";
904 ast_cli(a->
fd,
"No console device is set as active\n");
912 if (!strcasecmp(s,
"mute"))
914 else if (!strcasecmp(s,
"unmute"))
920 pvt->
muted ?
"Muted" :
"Unmuted");
929 PaDeviceIndex idx, num, def_input, def_output;
932 e->
command =
"console list available";
934 "Usage: console list available\n"
935 " List all available devices.\n";
944 "=============================================================\n"
945 "=== Available Devices =======================================\n"
946 "=============================================================\n"
949 num = Pa_GetDeviceCount();
955 def_input = Pa_GetDefaultInputDevice();
956 def_output = Pa_GetDefaultOutputDevice();
957 for (idx = 0; idx < num; idx++) {
958 const PaDeviceInfo *dev = Pa_GetDeviceInfo(idx);
961 ast_cli(a->
fd,
"=== ---------------------------------------------------------\n"
962 "=== Device Name: %s\n", dev->name);
963 if (dev->maxInputChannels)
964 ast_cli(a->
fd,
"=== ---> %sInput Device\n", (idx == def_input) ?
"Default " :
"");
965 if (dev->maxOutputChannels)
966 ast_cli(a->
fd,
"=== ---> %sOutput Device\n", (idx == def_output) ?
"Default " :
"");
967 ast_cli(a->
fd,
"=== ---------------------------------------------------------\n===\n");
970 ast_cli(a->
fd,
"=============================================================\n\n");
981 e->
command =
"console list devices";
983 "Usage: console list devices\n"
984 " List all configured devices.\n";
993 "=============================================================\n"
994 "=== Configured Devices ======================================\n"
995 "=============================================================\n"
1002 ast_cli(a->
fd,
"=== ---------------------------------------------------------\n"
1003 "=== Device Name: %s\n"
1004 "=== ---> Active: %s\n"
1005 "=== ---> Input Device: %s\n"
1006 "=== ---> Output Device: %s\n"
1007 "=== ---> Context: %s\n"
1008 "=== ---> Extension: %s\n"
1009 "=== ---> CallerID Num: %s\n"
1010 "=== ---> CallerID Name: %s\n"
1011 "=== ---> MOH Interpret: %s\n"
1012 "=== ---> Language: %s\n"
1013 "=== ---> Parkinglot: %s\n"
1014 "=== ---> Muted: %s\n"
1015 "=== ---> Auto-Answer: %s\n"
1016 "=== ---> Override Context: %s\n"
1017 "=== ---------------------------------------------------------\n===\n",
1018 pvt->
name, (pvt == active_pvt) ?
"Yes" :
"No",
1029 ast_cli(a->
fd,
"=============================================================\n\n");
1042 e->
command =
"console answer";
1044 "Usage: console answer\n"
1045 " Answers an incoming call on the console channel.\n";
1053 ast_cli(a->
fd,
"No console device is set as active\n");
1063 ast_cli(a->
fd,
"No one is calling us\n");
1092 .src =
"console_send_text",
1097 e->
command =
"console send text";
1099 "Usage: console send text <message>\n"
1100 " Sends a text message for display on the remote terminal.\n";
1106 ast_cli(a->
fd,
"No console device is set as active\n");
1161 e->
command =
"console {set|show} active";
1163 "Usage: console {set|show} active [<device>]\n"
1164 " Set or show the active console device for the Asterisk CLI.\n";
1173 if (++x > a->
n && !strncasecmp(pvt->
name, a->
word, strlen(a->
word)))
1193 ast_cli(a->
fd,
"No device is currently set as the active console device.\n");
1196 ast_cli(a->
fd,
"The active console device is '%s'.\n", pvt->
name);
1212 ast_cli(a->
fd,
"The active console device has been set to '%s'\n", pvt->
name);
1275 cid_num,
sizeof(cid_num));
1378 if (active_pvt == pvt)
1422 if (strcasecmp(context,
"general"))
1490 res = Pa_Initialize();
1491 if (res != paNoError) {
1493 res, Pa_GetErrorText(res));
1494 goto return_error_pa_init;
1499 goto return_error_chan_reg;
1503 goto return_error_cli_reg;
1507 return_error_cli_reg:
1509 return_error_chan_reg:
1511 return_error_pa_init:
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
union ast_frame_subclass subclass
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
static int open_stream(struct console_pvt *pvt)
static char * cli_console_sendtext(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Console send text CLI command.
#define ast_rwlock_rdlock(a)
static char mohinterpret[MAX_MUSICCLASS]
static char exten[AST_MAX_EXTENSION]
Main Channel structure associated with a channel.
static int pvt_hash_cb(const void *obj, const int flags)
#define AST_CLI_DEFINE(fn, txt,...)
char * str
Subscriber phone number (Malloced)
Asterisk main include file. File version handling, generic pbx functions.
#define ao2_link(arg1, arg2)
#define AST_RWLOCK_DEFINE_STATIC(rwlock)
static char parkinglot[AST_MAX_CONTEXT]
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame with payload.
struct ast_frame ast_null_frame
struct ast_party_caller caller
Channel Caller ID information.
static void stop_streams(void)
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
static void build_device(struct ast_config *cfg, const char *name)
const ast_string_field cid_num
static char * cli_console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * cli_console_active(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
static char * cli_console_autoanswer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define AST_CAUSE_SWITCH_CONGESTION
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
static int console_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
const ast_string_field context
struct ast_party_name name
Subscriber name.
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
static void set_pvt_defaults(struct console_pvt *pvt)
Set default values for a pvt struct.
static struct ast_jb_conf global_jbconf
#define ao2_iterator_next(arg1)
static char * cli_console_mute(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
descriptor for a cli entry.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
#define ao2_callback(c, flags, cb_fn, arg)
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
static char * cli_console_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Structure for variables, used for configurations and for channel variables.
unsigned int overridecontext
char * str
Subscriber name (Malloced)
static int console_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen)
static int load_config(int reload)
Load the configuration.
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
static int start_stream(struct console_pvt *pvt)
#define ast_mutex_lock(a)
struct ast_channel * owner
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 ...
static int console_digit_begin(struct ast_channel *c, char digit)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
const ast_string_field parkinglot
static int unload_module(void)
static ast_mutex_t globals_lock
static struct console_pvt * unref_pvt(struct console_pvt *pvt)
static char * cli_list_available(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define SAMPLE_RATE
The sample rate to request from PortAudio.
void ast_cli(int fd, const char *fmt,...)
static int console_hangup(struct ast_channel *c)
const ast_string_field linkedid
#define ast_rwlock_unlock(a)
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
static char cid_num[AST_MAX_EXTENSION]
#define ast_verb(level,...)
void ast_config_destroy(struct ast_config *config)
Destroys a config.
struct ast_channel * ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt,...)
static int console_digit_end(struct ast_channel *c, char digit, unsigned int duration)
static void store_callerid(struct console_pvt *pvt, const char *value)
int args
This gets set in ast_cli_register()
static struct ast_frame * console_read(struct ast_channel *chan)
static char * ast_ext_ctx(struct console_pvt *pvt, const char *src, char **ext, char **ctx)
static struct ast_jb_conf default_jbconf
Global jitterbuffer configuration.
#define ast_pthread_create_background(a, b, c, d)
static struct ast_channel_tech console_tech
struct ast_party_id id
Caller party ID.
#define ast_debug(level,...)
Log a DEBUG message.
static struct ast_cli_entry cli_console[]
#define CV_END
close a variable parsing block
static int pvt_mark_destroy_cb(void *obj, void *arg, int flags)
General Asterisk PBX channel definitions.
#define CV_START(__in_var, __in_val)
the macro to open a block for variable parsing
#define TEXT_SIZE
Maximum text message length.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_config_load(filename, flags)
Load a config file.
#define AST_PTHREADT_NULL
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define AST_STRING_FIELD(name)
Declare a string field.
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
#define ao2_ref(o, delta)
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
#define NUM_SAMPLES
The number of samples to configure the portaudio stream for.
#define console_pvt_unlock(pvt)
unlock a console_pvt struct
static struct ast_channel * console_new(struct console_pvt *pvt, const char *ext, const char *ctx, int state, const char *linkedid)
static char language[MAX_LANGUAGE]
static struct console_pvt globals
static struct ao2_container * pvts
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
static void store_config_core(struct console_pvt *pvt, const char *var, const char *value)
Store a configuration parameter in a pvt struct.
#define AST_FORMAT_SLINEAR16
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Core PBX routines and definitions.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
#define OUTPUT_CHANNELS
Mono Output.
const ast_string_field language
static void * stream_monitor(void *data)
Stream monitor thread.
static int init_pvt(struct console_pvt *pvt, const char *name)
#define CV_BOOL(__x, __dst)
helper macros to assign the value to a BOOL, UINT, static string and dynamic string ...
ast_control_frame_type
Internal control frame subtype field values.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
static char * cli_console_answer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
answer command from the console
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const ast_string_field name
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
static int console_call(struct ast_channel *c, char *dest, int timeout)
#define ao2_alloc(data_size, destructor_fn)
static void set_active(struct console_pvt *pvt, const char *value)
static int load_module(void)
#define ao2_find(arg1, arg2, arg3)
static int console_write(struct ast_channel *chan, struct ast_frame *f)
static ast_rwlock_t active_lock
static int console_text(struct ast_channel *c, const char *text)
static struct console_pvt * ref_pvt(struct console_pvt *pvt)
const ast_string_field input_device
void ast_join(char *s, size_t len, const char *const w[])
#define INPUT_CHANNELS
Mono Input.
#define V_BEGIN
Dance, Kirby, Dance!
unsigned int flags
Combination of the AST_JB_ENABLED, AST_JB_FORCED and AST_JB_LOG flags.
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Structure used to handle boolean flags.
static char cid_name[AST_MAX_EXTENSION]
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
#define ast_rwlock_wrlock(a)
static void destroy_pvts(void)
#define CV_F(__pattern, __body)
call a generic function if the name matches.
static struct console_pvt * active_pvt
static struct ast_channel * console_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Standard Command Line Interface.
#define ao2_container_alloc(arg1, arg2, arg3)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
#define SUPPORTED_FORMATS
Formats natively supported by this module.
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
static int pvt_cmp_cb(void *obj, void *arg, int flags)
char * ast_getformatname_multiple(char *buf, size_t size, format_t format)
Get the names of a set of formats.
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
const ast_string_field mohinterpret
static char * cli_list_devices(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 struct console_pvt * get_active_pvt(void)
const ast_string_field output_device
enum ast_frame_type frametype
#define console_pvt_lock(pvt)
lock a console_pvt struct
struct ast_variable * next
#define CV_STRFIELD(__x, __obj, __field)
unsigned char valid
TRUE if the name information is valid/present.
#define CONFIG_STATUS_FILEINVALID
static char context[AST_MAX_CONTEXT]
static int console_answer(struct ast_channel *c)
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
static struct console_pvt * find_pvt(const char *name)
const ast_string_field name
static snd_pcm_format_t format
union ast_frame::@172 data
struct ast_channel_tech * tech
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
unsigned char valid
TRUE if the number information is valid/present.
#define ao2_unlink(arg1, arg2)
General jitterbuffer configuration.
static int stop_stream(struct console_pvt *pvt)
#define AST_MUTEX_DEFINE_STATIC(mutex)
const ast_string_field cid_name
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
const ast_string_field exten
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
static const char config_file[]
#define ast_mutex_unlock(a)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
struct ast_party_number number
Subscriber phone number.
static void pvt_destructor(void *obj)