#include "asterisk.h"
#include <sys/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"
Go to the source code of this file.
Data Structures | |
struct | console_pvt |
Console pvt structure. More... | |
#define | V_BEGIN " --- <(\"<) --- " |
Dance, Kirby, Dance! | |
#define | V_END " --- (>\")> ---\n" |
static int | console_answer (struct ast_channel *c) |
static int | console_call (struct ast_channel *c, 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_frame * | console_read (struct ast_channel *chan) |
static struct ast_channel * | console_request (const char *type, format_t format, const struct ast_channel *requestor, void *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) |
Defines | |
#define | console_pvt_lock(pvt) ao2_lock(pvt) |
lock a console_pvt struct | |
#define | console_pvt_unlock(pvt) ao2_unlock(pvt) |
unlock a console_pvt struct | |
#define | INPUT_CHANNELS 1 |
Mono Input. | |
#define | NUM_PVT_BUCKETS 7 |
#define | NUM_SAMPLES 320 |
The number of samples to configure the portaudio stream for. | |
#define | OUTPUT_CHANNELS 1 |
Mono Output. | |
#define | SAMPLE_RATE 16000 |
The sample rate to request from PortAudio. | |
#define | SUPPORTED_FORMATS ( AST_FORMAT_SLINEAR16 ) |
Formats natively supported by this module. | |
#define | TEXT_SIZE 256 |
Maximum text message length. | |
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) |
static void | build_device (struct ast_config *cfg, const char *name) |
static char * | cli_console_active (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | cli_console_answer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
answer command from the console | |
static char * | cli_console_autoanswer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | cli_console_dial (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | cli_console_flash (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | cli_console_hangup (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | cli_console_mute (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | cli_console_sendtext (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Console send text CLI command. | |
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_channel * | console_new (struct console_pvt *pvt, const char *ext, const char *ctx, int state, const char *linkedid) |
static void | destroy_pvts (void) |
static struct console_pvt * | find_pvt (const char *name) |
static struct console_pvt * | get_active_pvt (void) |
static int | init_pvt (struct console_pvt *pvt, const char *name) |
static int | load_config (int reload) |
Load the configuration. | |
static int | load_module (void) |
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_pvt * | ref_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. | |
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. | |
static void * | stream_monitor (void *data) |
Stream monitor thread. | |
static int | unload_module (void) |
static struct console_pvt * | unref_pvt (struct console_pvt *pvt) |
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 = "ac1f6a56484a8820659555499174e588" , .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 } |
static struct console_pvt * | active_pvt |
static struct ast_module_info * | ast_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. | |
static struct ast_jb_conf | global_jbconf |
static struct console_pvt | globals |
Console pvt structure. | |
static ast_mutex_t | globals_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
static struct ao2_container * | pvts |
Definition in file chan_console.c.
#define console_pvt_lock | ( | pvt | ) | ao2_lock(pvt) |
lock a console_pvt struct
Definition at line 226 of file chan_console.c.
Referenced by build_device(), cli_console_active(), cli_console_dial(), cli_list_devices(), console_call(), console_request(), start_stream(), and stop_stream().
#define console_pvt_unlock | ( | pvt | ) | ao2_unlock(pvt) |
unlock a console_pvt struct
Definition at line 229 of file chan_console.c.
Referenced by build_device(), cli_console_active(), cli_console_dial(), cli_list_devices(), console_call(), console_request(), start_stream(), and stop_stream().
#define INPUT_CHANNELS 1 |
#define NUM_PVT_BUCKETS 7 |
#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 90 of file chan_console.c.
Referenced by open_stream(), and stream_monitor().
#define OUTPUT_CHANNELS 1 |
#define SAMPLE_RATE 16000 |
The sample rate to request from PortAudio.
Definition at line 78 of file chan_console.c.
Referenced by ast_tone_detect_init(), goertzel_init(), and open_stream().
#define SUPPORTED_FORMATS ( AST_FORMAT_SLINEAR16 ) |
Formats natively supported by this module.
Definition at line 206 of file chan_console.c.
Referenced by console_request().
#define TEXT_SIZE 256 |
Maximum text message length.
Definition at line 103 of file chan_console.c.
Referenced by cli_console_sendtext(), and console_sendtext().
#define V_BEGIN " --- <(\"<) --- " |
Dance, Kirby, Dance!
Definition at line 106 of file chan_console.c.
Referenced by cli_console_mute(), console_answer(), console_call(), console_digit_begin(), console_digit_end(), console_hangup(), console_indicate(), and console_text().
#define V_END " --- (>\")> ---\n" |
Definition at line 107 of file chan_console.c.
Referenced by cli_console_mute(), console_answer(), console_call(), console_digit_begin(), console_digit_end(), console_hangup(), console_indicate(), and console_text().
static void __reg_module | ( | void | ) | [static] |
Definition at line 1532 of file chan_console.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1532 of file chan_console.c.
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.
Definition at line 660 of file chan_console.c.
References ast_strdup, and console_pvt::overridecontext.
Referenced by cli_console_dial(), console_dial(), and console_transfer().
00661 { 00662 if (ext == NULL || ctx == NULL) 00663 return NULL; /* error */ 00664 00665 *ext = *ctx = NULL; 00666 00667 if (src && *src != '\0') 00668 *ext = ast_strdup(src); 00669 00670 if (*ext == NULL) 00671 return NULL; 00672 00673 if (!pvt->overridecontext) { 00674 /* parse from the right */ 00675 *ctx = strrchr(*ext, '@'); 00676 if (*ctx) 00677 *(*ctx)++ = '\0'; 00678 } 00679 00680 return *ext; 00681 }
static void build_device | ( | struct ast_config * | cfg, | |
const char * | name | |||
) | [static] |
Definition at line 1332 of file chan_console.c.
References ao2_alloc, ao2_link, ast_variable_browse(), console_pvt_lock, console_pvt_unlock, find_pvt(), init_pvt(), 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(), and reload_config().
01333 { 01334 struct ast_variable *v; 01335 struct console_pvt *pvt; 01336 int new = 0; 01337 01338 if ((pvt = find_pvt(name))) { 01339 console_pvt_lock(pvt); 01340 set_pvt_defaults(pvt); 01341 pvt->destroy = 0; 01342 } else { 01343 if (!(pvt = ao2_alloc(sizeof(*pvt), pvt_destructor))) 01344 return; 01345 init_pvt(pvt, name); 01346 set_pvt_defaults(pvt); 01347 new = 1; 01348 } 01349 01350 for (v = ast_variable_browse(cfg, name); v; v = v->next) 01351 store_config_core(pvt, v->name, v->value); 01352 01353 if (new) 01354 ao2_link(pvts, pvt); 01355 else 01356 console_pvt_unlock(pvt); 01357 01358 unref_pvt(pvt); 01359 }
static char* cli_console_active | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1155 of file chan_console.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_strdup, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, console_pvt_lock, console_pvt_unlock, ast_cli_args::fd, find_pvt(), get_active_pvt(), ast_cli_args::n, console_pvt::name, ast_cli_args::pos, pvts, set_active(), unref_pvt(), ast_cli_entry::usage, and ast_cli_args::word.
01156 { 01157 struct console_pvt *pvt; 01158 01159 switch (cmd) { 01160 case CLI_INIT: 01161 e->command = "console {set|show} active"; 01162 e->usage = 01163 "Usage: console {set|show} active [<device>]\n" 01164 " Set or show the active console device for the Asterisk CLI.\n"; 01165 return NULL; 01166 case CLI_GENERATE: 01167 if (a->pos == e->args) { 01168 struct ao2_iterator i; 01169 int x = 0; 01170 char *res = NULL; 01171 i = ao2_iterator_init(pvts, 0); 01172 while ((pvt = ao2_iterator_next(&i))) { 01173 if (++x > a->n && !strncasecmp(pvt->name, a->word, strlen(a->word))) 01174 res = ast_strdup(pvt->name); 01175 unref_pvt(pvt); 01176 if (res) { 01177 ao2_iterator_destroy(&i); 01178 return res; 01179 } 01180 } 01181 ao2_iterator_destroy(&i); 01182 } 01183 return NULL; 01184 } 01185 01186 if (a->argc < e->args) 01187 return CLI_SHOWUSAGE; 01188 01189 if (a->argc == 3) { 01190 pvt = get_active_pvt(); 01191 01192 if (!pvt) 01193 ast_cli(a->fd, "No device is currently set as the active console device.\n"); 01194 else { 01195 console_pvt_lock(pvt); 01196 ast_cli(a->fd, "The active console device is '%s'.\n", pvt->name); 01197 console_pvt_unlock(pvt); 01198 pvt = unref_pvt(pvt); 01199 } 01200 01201 return CLI_SUCCESS; 01202 } 01203 01204 if (!(pvt = find_pvt(a->argv[e->args - 1]))) { 01205 ast_cli(a->fd, "Could not find a device called '%s'.\n", a->argv[e->args]); 01206 return CLI_FAILURE; 01207 } 01208 01209 set_active(pvt, "yes"); 01210 01211 console_pvt_lock(pvt); 01212 ast_cli(a->fd, "The active console device has been set to '%s'\n", pvt->name); 01213 console_pvt_unlock(pvt); 01214 01215 unref_pvt(pvt); 01216 01217 return CLI_SUCCESS; 01218 }
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 1036 of file chan_console.c.
References ast_cli_args::argc, 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, ast_cli_args::fd, get_active_pvt(), console_pvt::hookstate, console_pvt::owner, unref_pvt(), and ast_cli_entry::usage.
01037 { 01038 struct console_pvt *pvt = get_active_pvt(); 01039 01040 switch (cmd) { 01041 case CLI_INIT: 01042 e->command = "console answer"; 01043 e->usage = 01044 "Usage: console answer\n" 01045 " Answers an incoming call on the console channel.\n"; 01046 return NULL; 01047 01048 case CLI_GENERATE: 01049 return NULL; /* no completion */ 01050 } 01051 01052 if (!pvt) { 01053 ast_cli(a->fd, "No console device is set as active\n"); 01054 return CLI_FAILURE; 01055 } 01056 01057 if (a->argc != e->args) { 01058 unref_pvt(pvt); 01059 return CLI_SHOWUSAGE; 01060 } 01061 01062 if (!pvt->owner) { 01063 ast_cli(a->fd, "No one is calling us\n"); 01064 unref_pvt(pvt); 01065 return CLI_FAILURE; 01066 } 01067 01068 pvt->hookstate = 1; 01069 01070 ast_indicate(pvt->owner, -1); 01071 01072 ast_queue_control(pvt->owner, AST_CONTROL_ANSWER); 01073 01074 unref_pvt(pvt); 01075 01076 return CLI_SUCCESS; 01077 }
static char* cli_console_autoanswer | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 694 of file chan_console.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), console_pvt::autoanswer, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_active_pvt(), unref_pvt(), and ast_cli_entry::usage.
00696 { 00697 struct console_pvt *pvt = get_active_pvt(); 00698 char *res = CLI_SUCCESS; 00699 00700 switch (cmd) { 00701 case CLI_INIT: 00702 e->command = "console {set|show} autoanswer [on|off]"; 00703 e->usage = 00704 "Usage: console {set|show} autoanswer [on|off]\n" 00705 " Enables or disables autoanswer feature. If used without\n" 00706 " argument, displays the current on/off status of autoanswer.\n" 00707 " The default value of autoanswer is in 'oss.conf'.\n"; 00708 return NULL; 00709 00710 case CLI_GENERATE: 00711 return NULL; 00712 } 00713 00714 if (!pvt) { 00715 ast_cli(a->fd, "No console device is set as active.\n"); 00716 return CLI_FAILURE; 00717 } 00718 00719 if (a->argc == e->args - 1) { 00720 ast_cli(a->fd, "Auto answer is %s.\n", pvt->autoanswer ? "on" : "off"); 00721 unref_pvt(pvt); 00722 return CLI_SUCCESS; 00723 } 00724 00725 if (a->argc != e->args) { 00726 unref_pvt(pvt); 00727 return CLI_SHOWUSAGE; 00728 } 00729 00730 if (!strcasecmp(a->argv[e->args-1], "on")) 00731 pvt->autoanswer = 1; 00732 else if (!strcasecmp(a->argv[e->args - 1], "off")) 00733 pvt->autoanswer = 0; 00734 else 00735 res = CLI_SHOWUSAGE; 00736 00737 unref_pvt(pvt); 00738 00739 return res; 00740 }
static char* cli_console_dial | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 778 of file chan_console.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_debug, ast_exists_extension(), ast_ext_ctx(), AST_FRAME_DTMF, 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, f, ast_cli_args::fd, free, get_active_pvt(), console_pvt::owner, unref_pvt(), and ast_cli_entry::usage.
00779 { 00780 char *s = NULL; 00781 const char *mye = NULL, *myc = NULL; 00782 struct console_pvt *pvt = get_active_pvt(); 00783 00784 if (cmd == CLI_INIT) { 00785 e->command = "console dial"; 00786 e->usage = 00787 "Usage: console dial [extension[@context]]\n" 00788 " Dials a given extension (and context if specified)\n"; 00789 return NULL; 00790 } else if (cmd == CLI_GENERATE) 00791 return NULL; 00792 00793 if (!pvt) { 00794 ast_cli(a->fd, "No console device is currently set as active\n"); 00795 return CLI_FAILURE; 00796 } 00797 00798 if (a->argc > e->args + 1) 00799 return CLI_SHOWUSAGE; 00800 00801 if (pvt->owner) { /* already in a call */ 00802 int i; 00803 struct ast_frame f = { AST_FRAME_DTMF }; 00804 const char *s; 00805 00806 if (a->argc == e->args) { /* argument is mandatory here */ 00807 ast_cli(a->fd, "Already in a call. You can only dial digits until you hangup.\n"); 00808 unref_pvt(pvt); 00809 return CLI_FAILURE; 00810 } 00811 s = a->argv[e->args]; 00812 /* send the string one char at a time */ 00813 for (i = 0; i < strlen(s); i++) { 00814 f.subclass.integer = s[i]; 00815 ast_queue_frame(pvt->owner, &f); 00816 } 00817 unref_pvt(pvt); 00818 return CLI_SUCCESS; 00819 } 00820 00821 /* if we have an argument split it into extension and context */ 00822 if (a->argc == e->args + 1) { 00823 char *ext = NULL, *con = NULL; 00824 s = ast_ext_ctx(pvt, a->argv[e->args], &ext, &con); 00825 ast_debug(1, "provided '%s', exten '%s' context '%s'\n", 00826 a->argv[e->args], mye, myc); 00827 mye = ext; 00828 myc = con; 00829 } 00830 00831 /* supply default values if needed */ 00832 if (ast_strlen_zero(mye)) 00833 mye = pvt->exten; 00834 if (ast_strlen_zero(myc)) 00835 myc = pvt->context; 00836 00837 if (ast_exists_extension(NULL, myc, mye, 1, NULL)) { 00838 console_pvt_lock(pvt); 00839 pvt->hookstate = 1; 00840 console_new(pvt, mye, myc, AST_STATE_RINGING, NULL); 00841 console_pvt_unlock(pvt); 00842 } else 00843 ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc); 00844 00845 free(s); 00846 00847 unref_pvt(pvt); 00848 00849 return CLI_SUCCESS; 00850 }
static char* cli_console_flash | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 742 of file chan_console.c.
References ast_cli_args::argc, 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, ast_cli_args::fd, get_active_pvt(), console_pvt::hookstate, console_pvt::owner, unref_pvt(), and ast_cli_entry::usage.
00743 { 00744 struct console_pvt *pvt = get_active_pvt(); 00745 00746 if (cmd == CLI_INIT) { 00747 e->command = "console flash"; 00748 e->usage = 00749 "Usage: console flash\n" 00750 " Flashes the call currently placed on the console.\n"; 00751 return NULL; 00752 } else if (cmd == CLI_GENERATE) 00753 return NULL; 00754 00755 if (!pvt) { 00756 ast_cli(a->fd, "No console device is set as active\n"); 00757 return CLI_FAILURE; 00758 } 00759 00760 if (a->argc != e->args) 00761 return CLI_SHOWUSAGE; 00762 00763 if (!pvt->owner) { 00764 ast_cli(a->fd, "No call to flash\n"); 00765 unref_pvt(pvt); 00766 return CLI_FAILURE; 00767 } 00768 00769 pvt->hookstate = 0; 00770 00771 ast_queue_control(pvt->owner, AST_CONTROL_FLASH); 00772 00773 unref_pvt(pvt); 00774 00775 return CLI_SUCCESS; 00776 }
static char* cli_console_hangup | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 852 of file chan_console.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), ast_queue_hangup(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_active_pvt(), console_pvt::hookstate, console_pvt::owner, unref_pvt(), and ast_cli_entry::usage.
00853 { 00854 struct console_pvt *pvt = get_active_pvt(); 00855 00856 if (cmd == CLI_INIT) { 00857 e->command = "console hangup"; 00858 e->usage = 00859 "Usage: console hangup\n" 00860 " Hangs up any call currently placed on the console.\n"; 00861 return NULL; 00862 } else if (cmd == CLI_GENERATE) 00863 return NULL; 00864 00865 if (!pvt) { 00866 ast_cli(a->fd, "No console device is set as active\n"); 00867 return CLI_FAILURE; 00868 } 00869 00870 if (a->argc != e->args) 00871 return CLI_SHOWUSAGE; 00872 00873 if (!pvt->owner && !pvt->hookstate) { 00874 ast_cli(a->fd, "No call to hang up\n"); 00875 unref_pvt(pvt); 00876 return CLI_FAILURE; 00877 } 00878 00879 pvt->hookstate = 0; 00880 if (pvt->owner) 00881 ast_queue_hangup(pvt->owner); 00882 00883 unref_pvt(pvt); 00884 00885 return CLI_SUCCESS; 00886 }
static char* cli_console_mute | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 888 of file chan_console.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_verb, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, get_active_pvt(), console_pvt::muted, unref_pvt(), ast_cli_entry::usage, V_BEGIN, and V_END.
00889 { 00890 const char *s; 00891 struct console_pvt *pvt = get_active_pvt(); 00892 char *res = CLI_SUCCESS; 00893 00894 if (cmd == CLI_INIT) { 00895 e->command = "console {mute|unmute}"; 00896 e->usage = 00897 "Usage: console {mute|unmute}\n" 00898 " Mute/unmute the microphone.\n"; 00899 return NULL; 00900 } else if (cmd == CLI_GENERATE) 00901 return NULL; 00902 00903 if (!pvt) { 00904 ast_cli(a->fd, "No console device is set as active\n"); 00905 return CLI_FAILURE; 00906 } 00907 00908 if (a->argc != e->args) 00909 return CLI_SHOWUSAGE; 00910 00911 s = a->argv[e->args-1]; 00912 if (!strcasecmp(s, "mute")) 00913 pvt->muted = 1; 00914 else if (!strcasecmp(s, "unmute")) 00915 pvt->muted = 0; 00916 else 00917 res = CLI_SHOWUSAGE; 00918 00919 ast_verb(1, V_BEGIN "The Console is now %s" V_END, 00920 pvt->muted ? "Muted" : "Unmuted"); 00921 00922 unref_pvt(pvt); 00923 00924 return res; 00925 }
static char* cli_console_sendtext | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Console send text CLI command.
Definition at line 1085 of file chan_console.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), AST_FRAME_TEXT, ast_join(), ast_queue_frame(), ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, f, ast_cli_args::fd, get_active_pvt(), len(), console_pvt::owner, TEXT_SIZE, unref_pvt(), and ast_cli_entry::usage.
01086 { 01087 char buf[TEXT_SIZE]; 01088 struct console_pvt *pvt = get_active_pvt(); 01089 struct ast_frame f = { 01090 .frametype = AST_FRAME_TEXT, 01091 .data.ptr = buf, 01092 .src = "console_send_text", 01093 }; 01094 int len; 01095 01096 if (cmd == CLI_INIT) { 01097 e->command = "console send text"; 01098 e->usage = 01099 "Usage: console send text <message>\n" 01100 " Sends a text message for display on the remote terminal.\n"; 01101 return NULL; 01102 } else if (cmd == CLI_GENERATE) 01103 return NULL; 01104 01105 if (!pvt) { 01106 ast_cli(a->fd, "No console device is set as active\n"); 01107 return CLI_FAILURE; 01108 } 01109 01110 if (a->argc < e->args + 1) { 01111 unref_pvt(pvt); 01112 return CLI_SHOWUSAGE; 01113 } 01114 01115 if (!pvt->owner) { 01116 ast_cli(a->fd, "Not in a call\n"); 01117 unref_pvt(pvt); 01118 return CLI_FAILURE; 01119 } 01120 01121 ast_join(buf, sizeof(buf) - 1, a->argv + e->args); 01122 if (ast_strlen_zero(buf)) { 01123 unref_pvt(pvt); 01124 return CLI_SHOWUSAGE; 01125 } 01126 01127 len = strlen(buf); 01128 buf[len] = '\n'; 01129 f.datalen = len + 1; 01130 01131 ast_queue_frame(pvt->owner, &f); 01132 01133 unref_pvt(pvt); 01134 01135 return CLI_SUCCESS; 01136 }
static char* cli_list_available | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 927 of file chan_console.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
00928 { 00929 PaDeviceIndex idx, num, def_input, def_output; 00930 00931 if (cmd == CLI_INIT) { 00932 e->command = "console list available"; 00933 e->usage = 00934 "Usage: console list available\n" 00935 " List all available devices.\n"; 00936 return NULL; 00937 } else if (cmd == CLI_GENERATE) 00938 return NULL; 00939 00940 if (a->argc != e->args) 00941 return CLI_SHOWUSAGE; 00942 00943 ast_cli(a->fd, "\n" 00944 "=============================================================\n" 00945 "=== Available Devices =======================================\n" 00946 "=============================================================\n" 00947 "===\n"); 00948 00949 num = Pa_GetDeviceCount(); 00950 if (!num) { 00951 ast_cli(a->fd, "(None)\n"); 00952 return CLI_SUCCESS; 00953 } 00954 00955 def_input = Pa_GetDefaultInputDevice(); 00956 def_output = Pa_GetDefaultOutputDevice(); 00957 for (idx = 0; idx < num; idx++) { 00958 const PaDeviceInfo *dev = Pa_GetDeviceInfo(idx); 00959 if (!dev) 00960 continue; 00961 ast_cli(a->fd, "=== ---------------------------------------------------------\n" 00962 "=== Device Name: %s\n", dev->name); 00963 if (dev->maxInputChannels) 00964 ast_cli(a->fd, "=== ---> %sInput Device\n", (idx == def_input) ? "Default " : ""); 00965 if (dev->maxOutputChannels) 00966 ast_cli(a->fd, "=== ---> %sOutput Device\n", (idx == def_output) ? "Default " : ""); 00967 ast_cli(a->fd, "=== ---------------------------------------------------------\n===\n"); 00968 } 00969 00970 ast_cli(a->fd, "=============================================================\n\n"); 00971 00972 return CLI_SUCCESS; 00973 }
static char* cli_list_devices | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 975 of file chan_console.c.
References active_pvt, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_args::argc, ast_cli_entry::args, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, console_pvt_lock, console_pvt_unlock, ast_cli_args::fd, pvts, unref_pvt(), and ast_cli_entry::usage.
00976 { 00977 struct ao2_iterator i; 00978 struct console_pvt *pvt; 00979 00980 if (cmd == CLI_INIT) { 00981 e->command = "console list devices"; 00982 e->usage = 00983 "Usage: console list devices\n" 00984 " List all configured devices.\n"; 00985 return NULL; 00986 } else if (cmd == CLI_GENERATE) 00987 return NULL; 00988 00989 if (a->argc != e->args) 00990 return CLI_SHOWUSAGE; 00991 00992 ast_cli(a->fd, "\n" 00993 "=============================================================\n" 00994 "=== Configured Devices ======================================\n" 00995 "=============================================================\n" 00996 "===\n"); 00997 00998 i = ao2_iterator_init(pvts, 0); 00999 while ((pvt = ao2_iterator_next(&i))) { 01000 console_pvt_lock(pvt); 01001 01002 ast_cli(a->fd, "=== ---------------------------------------------------------\n" 01003 "=== Device Name: %s\n" 01004 "=== ---> Active: %s\n" 01005 "=== ---> Input Device: %s\n" 01006 "=== ---> Output Device: %s\n" 01007 "=== ---> Context: %s\n" 01008 "=== ---> Extension: %s\n" 01009 "=== ---> CallerID Num: %s\n" 01010 "=== ---> CallerID Name: %s\n" 01011 "=== ---> MOH Interpret: %s\n" 01012 "=== ---> Language: %s\n" 01013 "=== ---> Parkinglot: %s\n" 01014 "=== ---> Muted: %s\n" 01015 "=== ---> Auto-Answer: %s\n" 01016 "=== ---> Override Context: %s\n" 01017 "=== ---------------------------------------------------------\n===\n", 01018 pvt->name, (pvt == active_pvt) ? "Yes" : "No", 01019 pvt->input_device, pvt->output_device, pvt->context, 01020 pvt->exten, pvt->cid_num, pvt->cid_name, pvt->mohinterpret, 01021 pvt->language, pvt->parkinglot, pvt->muted ? "Yes" : "No", pvt->autoanswer ? "Yes" : "No", 01022 pvt->overridecontext ? "Yes" : "No"); 01023 01024 console_pvt_unlock(pvt); 01025 unref_pvt(pvt); 01026 } 01027 ao2_iterator_destroy(&i); 01028 01029 ast_cli(a->fd, "=============================================================\n\n"); 01030 01031 return CLI_SUCCESS; 01032 }
static int console_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 527 of file chan_console.c.
References ast_setstate(), AST_STATE_UP, ast_verb, start_stream(), ast_channel::tech_pvt, V_BEGIN, and V_END.
00528 { 00529 struct console_pvt *pvt = c->tech_pvt; 00530 00531 ast_verb(1, V_BEGIN "Call from Console has been Answered" V_END); 00532 00533 ast_setstate(c, AST_STATE_UP); 00534 00535 return start_stream(pvt); 00536 }
static int console_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 565 of file chan_console.c.
References AST_CONTROL_ANSWER, AST_CONTROL_RINGING, ast_indicate(), ast_queue_control(), ast_verb, console_pvt::autoanswer, ast_channel::caller, console_pvt_lock, console_pvt_unlock, console_pvt::hookstate, ast_party_caller::id, ast_party_id::name, ast_party_id::number, S_COR, start_stream(), ast_party_number::str, ast_party_name::str, ast_channel::tech_pvt, V_BEGIN, V_END, ast_party_number::valid, and ast_party_name::valid.
00566 { 00567 struct console_pvt *pvt = c->tech_pvt; 00568 enum ast_control_frame_type ctrl; 00569 00570 ast_verb(1, V_BEGIN "Call to device '%s' on console from '%s' <%s>" V_END, 00571 dest, 00572 S_COR(c->caller.id.name.valid, c->caller.id.name.str, ""), 00573 S_COR(c->caller.id.number.valid, c->caller.id.number.str, "")); 00574 00575 console_pvt_lock(pvt); 00576 00577 if (pvt->autoanswer) { 00578 pvt->hookstate = 1; 00579 console_pvt_unlock(pvt); 00580 ast_verb(1, V_BEGIN "Auto-answered" V_END); 00581 ctrl = AST_CONTROL_ANSWER; 00582 } else { 00583 console_pvt_unlock(pvt); 00584 ast_verb(1, V_BEGIN "Type 'console answer' to answer, or use the 'autoanswer' option " 00585 "for future calls" V_END); 00586 ctrl = AST_CONTROL_RINGING; 00587 ast_indicate(c, AST_CONTROL_RINGING); 00588 } 00589 00590 ast_queue_control(c, ctrl); 00591 00592 return start_stream(pvt); 00593 }
static int console_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
static int console_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
static int console_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 640 of file chan_console.c.
References console_pvt::owner, and ast_channel::tech_pvt.
00641 { 00642 struct console_pvt *pvt = newchan->tech_pvt; 00643 00644 pvt->owner = newchan; 00645 00646 return 0; 00647 }
static int console_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 512 of file chan_console.c.
References ast_verb, console_pvt::hookstate, console_pvt::owner, stop_stream(), ast_channel::tech_pvt, unref_pvt(), V_BEGIN, and V_END.
00513 { 00514 struct console_pvt *pvt = c->tech_pvt; 00515 00516 ast_verb(1, V_BEGIN "Hangup on Console" V_END); 00517 00518 pvt->hookstate = 0; 00519 pvt->owner = NULL; 00520 stop_stream(pvt); 00521 00522 c->tech_pvt = unref_pvt(pvt); 00523 00524 return 0; 00525 }
static int console_indicate | ( | struct ast_channel * | chan, | |
int | cond, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 604 of file chan_console.c.
References AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_verb, LOG_WARNING, console_pvt::mohinterpret, ast_channel::name, ast_channel::tech_pvt, V_BEGIN, and V_END.
00605 { 00606 struct console_pvt *pvt = chan->tech_pvt; 00607 int res = 0; 00608 00609 switch (cond) { 00610 case AST_CONTROL_BUSY: 00611 case AST_CONTROL_CONGESTION: 00612 case AST_CONTROL_RINGING: 00613 case AST_CONTROL_INCOMPLETE: 00614 case -1: 00615 res = -1; /* Ask for inband indications */ 00616 break; 00617 case AST_CONTROL_PROGRESS: 00618 case AST_CONTROL_PROCEEDING: 00619 case AST_CONTROL_VIDUPDATE: 00620 case AST_CONTROL_SRCUPDATE: 00621 break; 00622 case AST_CONTROL_HOLD: 00623 ast_verb(1, V_BEGIN "Console Has Been Placed on Hold" V_END); 00624 ast_moh_start(chan, data, pvt->mohinterpret); 00625 break; 00626 case AST_CONTROL_UNHOLD: 00627 ast_verb(1, V_BEGIN "Console Has Been Retrieved from Hold" V_END); 00628 ast_moh_stop(chan); 00629 break; 00630 default: 00631 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", 00632 cond, chan->name); 00633 /* The core will play inband indications for us if appropriate */ 00634 res = -1; 00635 } 00636 00637 return res; 00638 }
static struct ast_channel* console_new | ( | struct console_pvt * | pvt, | |
const char * | ext, | |||
const char * | ctx, | |||
int | state, | |||
const char * | linkedid | |||
) | [static] |
Definition at line 419 of file chan_console.c.
References AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc, AST_FORMAT_SLINEAR16, ast_hangup(), ast_jb_configure(), ast_pbx_start(), AST_STATE_DOWN, ast_string_field_set, ast_strlen_zero(), console_pvt::cid_name, console_pvt::cid_num, console_tech, global_jbconf, language, console_pvt::language, console_pvt::name, ast_channel::nativeformats, console_pvt::owner, ast_channel::readformat, ref_pvt(), start_stream(), ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat.
Referenced by cli_console_dial(), and console_request().
00420 { 00421 struct ast_channel *chan; 00422 00423 if (!(chan = ast_channel_alloc(1, state, pvt->cid_num, pvt->cid_name, NULL, 00424 ext, ctx, linkedid, 0, "Console/%s", pvt->name))) { 00425 return NULL; 00426 } 00427 00428 chan->tech = &console_tech; 00429 chan->nativeformats = AST_FORMAT_SLINEAR16; 00430 chan->readformat = AST_FORMAT_SLINEAR16; 00431 chan->writeformat = AST_FORMAT_SLINEAR16; 00432 chan->tech_pvt = ref_pvt(pvt); 00433 00434 pvt->owner = chan; 00435 00436 if (!ast_strlen_zero(pvt->language)) 00437 ast_string_field_set(chan, language, pvt->language); 00438 00439 ast_jb_configure(chan, &global_jbconf); 00440 00441 if (state != AST_STATE_DOWN) { 00442 if (ast_pbx_start(chan)) { 00443 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 00444 ast_hangup(chan); 00445 chan = NULL; 00446 } else 00447 start_stream(pvt); 00448 } 00449 00450 return chan; 00451 }
static struct ast_frame * console_read | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 558 of file chan_console.c.
References ast_debug, and ast_null_frame.
00559 { 00560 ast_debug(1, "I should not be called ...\n"); 00561 00562 return &ast_null_frame; 00563 }
static struct ast_channel * console_request | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Channel Technology Callbacks
Definition at line 453 of file chan_console.c.
References AST_CAUSE_BUSY, ast_getformatname_multiple(), ast_log(), AST_STATE_DOWN, console_new(), console_pvt_lock, console_pvt_unlock, find_pvt(), ast_channel::linkedid, LOG_NOTICE, LOG_WARNING, console_pvt::owner, SUPPORTED_FORMATS, and unref_pvt().
00454 { 00455 format_t oldformat = format; 00456 struct ast_channel *chan = NULL; 00457 struct console_pvt *pvt; 00458 char buf[512]; 00459 00460 if (!(pvt = find_pvt(data))) { 00461 ast_log(LOG_ERROR, "Console device '%s' not found\n", (char *) data); 00462 return NULL; 00463 } 00464 00465 format &= SUPPORTED_FORMATS; 00466 if (!format) { 00467 ast_log(LOG_NOTICE, "Channel requested with unsupported format(s): '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), oldformat)); 00468 goto return_unref; 00469 } 00470 00471 if (pvt->owner) { 00472 ast_log(LOG_NOTICE, "Console channel already active!\n"); 00473 *cause = AST_CAUSE_BUSY; 00474 goto return_unref; 00475 } 00476 00477 console_pvt_lock(pvt); 00478 chan = console_new(pvt, NULL, NULL, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL); 00479 console_pvt_unlock(pvt); 00480 00481 if (!chan) 00482 ast_log(LOG_WARNING, "Unable to create new Console channel!\n"); 00483 00484 return_unref: 00485 unref_pvt(pvt); 00486 00487 return chan; 00488 }
static int console_text | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
static int console_write | ( | struct ast_channel * | chan, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 595 of file chan_console.c.
References f, console_pvt::stream, and ast_channel::tech_pvt.
00596 { 00597 struct console_pvt *pvt = chan->tech_pvt; 00598 00599 Pa_WriteStream(pvt->stream, f->data.ptr, f->samples); 00600 00601 return 0; 00602 }
static void destroy_pvts | ( | void | ) | [static] |
Definition at line 1368 of file chan_console.c.
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().
01369 { 01370 struct ao2_iterator i; 01371 struct console_pvt *pvt; 01372 01373 i = ao2_iterator_init(pvts, 0); 01374 while ((pvt = ao2_iterator_next(&i))) { 01375 if (pvt->destroy) { 01376 ao2_unlink(pvts, pvt); 01377 ast_rwlock_wrlock(&active_lock); 01378 if (active_pvt == pvt) 01379 active_pvt = unref_pvt(pvt); 01380 ast_rwlock_unlock(&active_lock); 01381 } 01382 unref_pvt(pvt); 01383 } 01384 ao2_iterator_destroy(&i); 01385 }
static struct console_pvt* find_pvt | ( | const char * | name | ) | [static] |
Definition at line 244 of file chan_console.c.
References ao2_find, console_pvt::name, OBJ_POINTER, and pvts.
Referenced by build_device(), cli_console_active(), and console_request().
00245 { 00246 struct console_pvt tmp_pvt = { 00247 .name = name, 00248 }; 00249 00250 return ao2_find(pvts, &tmp_pvt, OBJ_POINTER); 00251 }
static struct console_pvt* get_active_pvt | ( | void | ) | [static] |
Definition at line 683 of file chan_console.c.
References active_lock, active_pvt, ast_rwlock_rdlock, ast_rwlock_unlock, and ref_pvt().
Referenced by cli_console_active(), cli_console_answer(), cli_console_autoanswer(), cli_console_dial(), cli_console_flash(), cli_console_hangup(), cli_console_mute(), and cli_console_sendtext().
00684 { 00685 struct console_pvt *pvt; 00686 00687 ast_rwlock_rdlock(&active_lock); 00688 pvt = ref_pvt(active_pvt); 00689 ast_rwlock_unlock(&active_lock); 00690 00691 return pvt; 00692 }
static int init_pvt | ( | struct console_pvt * | pvt, | |
const char * | name | |||
) | [static] |
Definition at line 1320 of file chan_console.c.
References AST_PTHREADT_NULL, ast_string_field_init, ast_string_field_set, S_OR, and console_pvt::thread.
Referenced by build_device(), and load_module().
01321 { 01322 pvt->thread = AST_PTHREADT_NULL; 01323 01324 if (ast_string_field_init(pvt, 32)) 01325 return -1; 01326 01327 ast_string_field_set(pvt, name, S_OR(name, "")); 01328 01329 return 0; 01330 }
static int load_config | ( | int | reload | ) | [static] |
Load the configuration.
reload | if this was called due to a reload |
0 | success | |
-1 | failure |
Definition at line 1393 of file chan_console.c.
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_STATUS_FILEINVALID, context, default_jbconf, destroy_pvts(), global_jbconf, globals, globals_lock, LOG_NOTICE, ast_variable::name, ast_variable::next, OBJ_NODATA, pvt_mark_destroy_cb(), pvts, set_pvt_defaults(), store_config_core(), and ast_variable::value.
01394 { 01395 struct ast_config *cfg; 01396 struct ast_variable *v; 01397 struct ast_flags config_flags = { 0 }; 01398 char *context = NULL; 01399 01400 /* default values */ 01401 memcpy(&global_jbconf, &default_jbconf, sizeof(global_jbconf)); 01402 ast_mutex_lock(&globals_lock); 01403 set_pvt_defaults(&globals); 01404 ast_mutex_unlock(&globals_lock); 01405 01406 if (!(cfg = ast_config_load(config_file, config_flags))) { 01407 ast_log(LOG_NOTICE, "Unable to open configuration file %s!\n", config_file); 01408 return -1; 01409 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 01410 ast_log(LOG_NOTICE, "Config file %s has an invalid format\n", config_file); 01411 return -1; 01412 } 01413 01414 ao2_callback(pvts, OBJ_NODATA, pvt_mark_destroy_cb, NULL); 01415 01416 ast_mutex_lock(&globals_lock); 01417 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) 01418 store_config_core(&globals, v->name, v->value); 01419 ast_mutex_unlock(&globals_lock); 01420 01421 while ((context = ast_category_browse(cfg, context))) { 01422 if (strcasecmp(context, "general")) 01423 build_device(cfg, context); 01424 } 01425 01426 ast_config_destroy(cfg); 01427 01428 destroy_pvts(); 01429 01430 return 0; 01431 }
static int load_module | ( | void | ) | [static] |
Definition at line 1478 of file chan_console.c.
References ao2_container_alloc, ao2_ref, ARRAY_LEN, ast_channel_register(), ast_channel_unregister(), ast_cli_register_multiple(), ast_cli_unregister_multiple(), ast_log(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, cli_console, console_tech, globals, init_pvt(), load_config(), LOG_WARNING, NUM_PVT_BUCKETS, pvt_cmp_cb(), pvt_destructor(), pvt_hash_cb(), and pvts.
01479 { 01480 PaError res; 01481 01482 init_pvt(&globals, NULL); 01483 01484 if (!(pvts = ao2_container_alloc(NUM_PVT_BUCKETS, pvt_hash_cb, pvt_cmp_cb))) 01485 goto return_error; 01486 01487 if (load_config(0)) 01488 goto return_error; 01489 01490 res = Pa_Initialize(); 01491 if (res != paNoError) { 01492 ast_log(LOG_WARNING, "Failed to initialize audio system - (%d) %s\n", 01493 res, Pa_GetErrorText(res)); 01494 goto return_error_pa_init; 01495 } 01496 01497 if (ast_channel_register(&console_tech)) { 01498 ast_log(LOG_ERROR, "Unable to register channel type 'Console'\n"); 01499 goto return_error_chan_reg; 01500 } 01501 01502 if (ast_cli_register_multiple(cli_console, ARRAY_LEN(cli_console))) 01503 goto return_error_cli_reg; 01504 01505 return AST_MODULE_LOAD_SUCCESS; 01506 01507 return_error_cli_reg: 01508 ast_cli_unregister_multiple(cli_console, ARRAY_LEN(cli_console)); 01509 return_error_chan_reg: 01510 ast_channel_unregister(&console_tech); 01511 return_error_pa_init: 01512 Pa_Terminate(); 01513 return_error: 01514 if (pvts) 01515 ao2_ref(pvts, -1); 01516 pvts = NULL; 01517 pvt_destructor(&globals); 01518 01519 return AST_MODULE_LOAD_DECLINE; 01520 }
static int open_stream | ( | struct console_pvt * | pvt | ) | [static] |
Definition at line 293 of file chan_console.c.
References INPUT_CHANNELS, console_pvt::input_device, NUM_SAMPLES, OUTPUT_CHANNELS, console_pvt::output_device, SAMPLE_RATE, and console_pvt::stream.
Referenced by start_stream().
00294 { 00295 int res = paInternalError; 00296 00297 if (!strcasecmp(pvt->input_device, "default") && 00298 !strcasecmp(pvt->output_device, "default")) { 00299 res = Pa_OpenDefaultStream(&pvt->stream, INPUT_CHANNELS, OUTPUT_CHANNELS, 00300 paInt16, SAMPLE_RATE, NUM_SAMPLES, NULL, NULL); 00301 } else { 00302 PaStreamParameters input_params = { 00303 .channelCount = 1, 00304 .sampleFormat = paInt16, 00305 .suggestedLatency = (1.0 / 50.0), /* 20 ms */ 00306 .device = paNoDevice, 00307 }; 00308 PaStreamParameters output_params = { 00309 .channelCount = 1, 00310 .sampleFormat = paInt16, 00311 .suggestedLatency = (1.0 / 50.0), /* 20 ms */ 00312 .device = paNoDevice, 00313 }; 00314 PaDeviceIndex idx, num_devices, def_input, def_output; 00315 00316 if (!(num_devices = Pa_GetDeviceCount())) 00317 return res; 00318 00319 def_input = Pa_GetDefaultInputDevice(); 00320 def_output = Pa_GetDefaultOutputDevice(); 00321 00322 for (idx = 0; 00323 idx < num_devices && (input_params.device == paNoDevice 00324 || output_params.device == paNoDevice); 00325 idx++) 00326 { 00327 const PaDeviceInfo *dev = Pa_GetDeviceInfo(idx); 00328 00329 if (dev->maxInputChannels) { 00330 if ( (idx == def_input && !strcasecmp(pvt->input_device, "default")) || 00331 !strcasecmp(pvt->input_device, dev->name) ) 00332 input_params.device = idx; 00333 } 00334 00335 if (dev->maxOutputChannels) { 00336 if ( (idx == def_output && !strcasecmp(pvt->output_device, "default")) || 00337 !strcasecmp(pvt->output_device, dev->name) ) 00338 output_params.device = idx; 00339 } 00340 } 00341 00342 if (input_params.device == paNoDevice) 00343 ast_log(LOG_ERROR, "No input device found for console device '%s'\n", pvt->name); 00344 if (output_params.device == paNoDevice) 00345 ast_log(LOG_ERROR, "No output device found for console device '%s'\n", pvt->name); 00346 00347 res = Pa_OpenStream(&pvt->stream, &input_params, &output_params, 00348 SAMPLE_RATE, NUM_SAMPLES, paNoFlag, NULL, NULL); 00349 } 00350 00351 return res; 00352 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1440 of file chan_console.c.
References CMP_MATCH, CMP_STOP, and console_pvt::name.
Referenced by load_module(), and load_objects().
01441 { 01442 struct console_pvt *pvt = obj, *pvt2 = arg; 01443 01444 return !strcasecmp(pvt->name, pvt2->name) ? CMP_MATCH | CMP_STOP : 0; 01445 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1313 of file chan_console.c.
References ast_string_field_free_memory.
Referenced by build_device(), load_module(), new_iax(), and unload_module().
01314 { 01315 struct console_pvt *pvt = obj; 01316 01317 ast_string_field_free_memory(pvt); 01318 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1433 of file chan_console.c.
References ast_str_case_hash(), and console_pvt::name.
Referenced by load_module(), and load_objects().
01434 { 01435 const struct console_pvt *pvt = obj; 01436 01437 return ast_str_case_hash(pvt->name); 01438 }
static int pvt_mark_destroy_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1361 of file chan_console.c.
References console_pvt::destroy.
Referenced by load_config().
01362 { 01363 struct console_pvt *pvt = obj; 01364 pvt->destroy = 1; 01365 return 0; 01366 }
static struct console_pvt* ref_pvt | ( | struct console_pvt * | pvt | ) | [inline, static] |
Definition at line 231 of file chan_console.c.
References ao2_ref.
Referenced by console_new(), get_active_pvt(), and set_active().
00232 { 00233 if (pvt) 00234 ao2_ref(pvt, +1); 00235 return pvt; 00236 }
static int reload | ( | void | ) | [static] |
Definition at line 1522 of file chan_console.c.
References load_config().
01523 { 01524 return load_config(1); 01525 }
static void set_active | ( | struct console_pvt * | pvt, | |
const char * | value | |||
) | [static] |
Definition at line 1138 of file chan_console.c.
References active_lock, active_pvt, ast_log(), ast_rwlock_unlock, ast_rwlock_wrlock, ast_true(), globals, ref_pvt(), and unref_pvt().
Referenced by cli_console_active(), and store_config_core().
01139 { 01140 if (pvt == &globals) { 01141 ast_log(LOG_ERROR, "active is only valid as a per-device setting\n"); 01142 return; 01143 } 01144 01145 if (!ast_true(value)) 01146 return; 01147 01148 ast_rwlock_wrlock(&active_lock); 01149 if (active_pvt) 01150 unref_pvt(active_pvt); 01151 active_pvt = ref_pvt(pvt); 01152 ast_rwlock_unlock(&active_lock); 01153 }
static void set_pvt_defaults | ( | struct console_pvt * | pvt | ) | [static] |
Set default values for a pvt struct.
Definition at line 1238 of file chan_console.c.
References ast_mutex_lock, ast_mutex_unlock, ast_string_field_set, console_pvt::autoanswer, console_pvt::cid_name, cid_name, console_pvt::cid_num, cid_num, console_pvt::context, context, console_pvt::exten, exten, globals, globals_lock, console_pvt::language, language, console_pvt::mohinterpret, mohinterpret, console_pvt::overridecontext, console_pvt::parkinglot, and parkinglot.
Referenced by build_device(), and load_config().
01239 { 01240 if (pvt == &globals) { 01241 ast_string_field_set(pvt, mohinterpret, "default"); 01242 ast_string_field_set(pvt, context, "default"); 01243 ast_string_field_set(pvt, exten, "s"); 01244 ast_string_field_set(pvt, language, ""); 01245 ast_string_field_set(pvt, cid_num, ""); 01246 ast_string_field_set(pvt, cid_name, ""); 01247 ast_string_field_set(pvt, parkinglot, ""); 01248 01249 pvt->overridecontext = 0; 01250 pvt->autoanswer = 0; 01251 } else { 01252 ast_mutex_lock(&globals_lock); 01253 01254 ast_string_field_set(pvt, mohinterpret, globals.mohinterpret); 01255 ast_string_field_set(pvt, context, globals.context); 01256 ast_string_field_set(pvt, exten, globals.exten); 01257 ast_string_field_set(pvt, language, globals.language); 01258 ast_string_field_set(pvt, cid_num, globals.cid_num); 01259 ast_string_field_set(pvt, cid_name, globals.cid_name); 01260 ast_string_field_set(pvt, parkinglot, globals.parkinglot); 01261 01262 pvt->overridecontext = globals.overridecontext; 01263 pvt->autoanswer = globals.autoanswer; 01264 01265 ast_mutex_unlock(&globals_lock); 01266 } 01267 }
static int start_stream | ( | struct console_pvt * | pvt | ) | [static] |
Definition at line 354 of file chan_console.c.
References ast_debug, ast_log(), ast_pthread_create_background, console_pvt_lock, console_pvt_unlock, LOG_WARNING, 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().
00355 { 00356 PaError res; 00357 int ret_val = 0; 00358 00359 console_pvt_lock(pvt); 00360 00361 /* It is possible for console_hangup to be called before the 00362 * stream is started, if this is the case pvt->owner will be NULL 00363 * and start_stream should be aborted. */ 00364 if (pvt->streamstate || !pvt->owner) 00365 goto return_unlock; 00366 00367 pvt->streamstate = 1; 00368 ast_debug(1, "Starting stream\n"); 00369 00370 res = open_stream(pvt); 00371 if (res != paNoError) { 00372 ast_log(LOG_WARNING, "Failed to open stream - (%d) %s\n", 00373 res, Pa_GetErrorText(res)); 00374 ret_val = -1; 00375 goto return_unlock; 00376 } 00377 00378 res = Pa_StartStream(pvt->stream); 00379 if (res != paNoError) { 00380 ast_log(LOG_WARNING, "Failed to start stream - (%d) %s\n", 00381 res, Pa_GetErrorText(res)); 00382 ret_val = -1; 00383 goto return_unlock; 00384 } 00385 00386 if (ast_pthread_create_background(&pvt->thread, NULL, stream_monitor, pvt)) { 00387 ast_log(LOG_ERROR, "Failed to start stream monitor thread\n"); 00388 ret_val = -1; 00389 } 00390 00391 return_unlock: 00392 console_pvt_unlock(pvt); 00393 00394 return ret_val; 00395 }
static int stop_stream | ( | struct console_pvt * | pvt | ) | [static] |
Definition at line 397 of file chan_console.c.
References AST_PTHREADT_NULL, console_pvt_lock, console_pvt_unlock, console_pvt::stream, console_pvt::streamstate, and console_pvt::thread.
Referenced by console_hangup(), and stop_streams().
00398 { 00399 if (!pvt->streamstate || pvt->thread == AST_PTHREADT_NULL) 00400 return 0; 00401 00402 pthread_cancel(pvt->thread); 00403 pthread_kill(pvt->thread, SIGURG); 00404 pthread_join(pvt->thread, NULL); 00405 00406 console_pvt_lock(pvt); 00407 Pa_AbortStream(pvt->stream); 00408 Pa_CloseStream(pvt->stream); 00409 pvt->stream = NULL; 00410 pvt->streamstate = 0; 00411 console_pvt_unlock(pvt); 00412 00413 return 0; 00414 }
static void stop_streams | ( | void | ) | [static] |
Definition at line 1447 of file chan_console.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, console_pvt::hookstate, pvts, stop_stream(), and unref_pvt().
Referenced by unload_module().
01448 { 01449 struct console_pvt *pvt; 01450 struct ao2_iterator i; 01451 01452 i = ao2_iterator_init(pvts, 0); 01453 while ((pvt = ao2_iterator_next(&i))) { 01454 if (pvt->hookstate) 01455 stop_stream(pvt); 01456 unref_pvt(pvt); 01457 } 01458 ao2_iterator_destroy(&i); 01459 }
static void store_callerid | ( | struct console_pvt * | pvt, | |
const char * | value | |||
) | [static] |
Definition at line 1269 of file chan_console.c.
References ast_callerid_split(), ast_string_field_set, cid_name, and cid_num.
Referenced by store_config_core().
01270 { 01271 char cid_name[256]; 01272 char cid_num[256]; 01273 01274 ast_callerid_split(value, cid_name, sizeof(cid_name), 01275 cid_num, sizeof(cid_num)); 01276 01277 ast_string_field_set(pvt, cid_name, cid_name); 01278 ast_string_field_set(pvt, cid_num, cid_num); 01279 }
static void store_config_core | ( | struct console_pvt * | pvt, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Store a configuration parameter in a pvt struct.
Definition at line 1286 of file chan_console.c.
References ast_jb_read_conf(), ast_log(), console_pvt::autoanswer, context, CV_BOOL, CV_END, CV_F, CV_START, CV_STRFIELD, exten, global_jbconf, globals, language, LOG_WARNING, mohinterpret, console_pvt::overridecontext, parkinglot, set_active(), and store_callerid().
Referenced by build_device(), console_cmd(), load_config(), and store_config().
01287 { 01288 if (pvt == &globals && !ast_jb_read_conf(&global_jbconf, var, value)) 01289 return; 01290 01291 CV_START(var, value); 01292 01293 CV_STRFIELD("context", pvt, context); 01294 CV_STRFIELD("extension", pvt, exten); 01295 CV_STRFIELD("mohinterpret", pvt, mohinterpret); 01296 CV_STRFIELD("language", pvt, language); 01297 CV_F("callerid", store_callerid(pvt, value)); 01298 CV_BOOL("overridecontext", pvt->overridecontext); 01299 CV_BOOL("autoanswer", pvt->autoanswer); 01300 CV_STRFIELD("parkinglot", pvt, parkinglot); 01301 01302 if (pvt != &globals) { 01303 CV_F("active", set_active(pvt, value)) 01304 CV_STRFIELD("input_device", pvt, input_device); 01305 CV_STRFIELD("output_device", pvt, output_device); 01306 } 01307 01308 ast_log(LOG_WARNING, "Unknown option '%s'\n", var); 01309 01310 CV_END; 01311 }
static void* stream_monitor | ( | void * | data | ) | [static] |
Stream monitor thread.
Definition at line 263 of file chan_console.c.
References AST_FORMAT_SLINEAR16, AST_FRAME_VOICE, ast_queue_frame(), f, NUM_SAMPLES, console_pvt::owner, ast_frame::samples, and console_pvt::stream.
Referenced by start_stream().
00264 { 00265 struct console_pvt *pvt = data; 00266 char buf[NUM_SAMPLES * sizeof(int16_t)]; 00267 PaError res; 00268 struct ast_frame f = { 00269 .frametype = AST_FRAME_VOICE, 00270 .subclass.codec = AST_FORMAT_SLINEAR16, 00271 .src = "console_stream_monitor", 00272 .data.ptr = buf, 00273 .datalen = sizeof(buf), 00274 .samples = sizeof(buf) / sizeof(int16_t), 00275 }; 00276 00277 for (;;) { 00278 pthread_testcancel(); 00279 res = Pa_ReadStream(pvt->stream, buf, sizeof(buf) / sizeof(int16_t)); 00280 pthread_testcancel(); 00281 00282 if (!pvt->owner) { 00283 return NULL; 00284 } 00285 00286 if (res == paNoError) 00287 ast_queue_frame(pvt->owner, &f); 00288 } 00289 00290 return NULL; 00291 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1461 of file chan_console.c.
References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), cli_console, console_tech, globals, pvt_destructor(), pvts, and stop_streams().
01462 { 01463 ast_channel_unregister(&console_tech); 01464 ast_cli_unregister_multiple(cli_console, ARRAY_LEN(cli_console)); 01465 01466 stop_streams(); 01467 01468 Pa_Terminate(); 01469 01470 /* Will unref all the pvts so they will get destroyed, too */ 01471 ao2_ref(pvts, -1); 01472 01473 pvt_destructor(&globals); 01474 01475 return 0; 01476 }
static struct console_pvt* unref_pvt | ( | struct console_pvt * | pvt | ) | [inline, static] |
Definition at line 238 of file chan_console.c.
References ao2_ref.
Referenced by build_device(), cli_console_active(), cli_console_answer(), cli_console_autoanswer(), cli_console_dial(), cli_console_flash(), cli_console_hangup(), cli_console_mute(), cli_console_sendtext(), cli_list_devices(), console_hangup(), console_request(), destroy_pvts(), set_active(), and stop_streams().
00239 { 00240 ao2_ref(pvt, -1); 00241 return NULL; 00242 }
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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, } [static] |
Definition at line 1532 of file chan_console.c.
ast_rwlock_t active_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } [static] |
Definition at line 170 of file chan_console.c.
Referenced by destroy_pvts(), get_active_pvt(), and set_active().
struct console_pvt* active_pvt [static] |
Definition at line 169 of file chan_console.c.
Referenced by cli_list_devices(), destroy_pvts(), get_active_pvt(), and set_active().
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1532 of file chan_console.c.
struct ast_cli_entry cli_console[] [static] |
const char config_file[] = "console.conf" [static] |
Definition at line 110 of file chan_console.c.
struct ast_channel_tech console_tech [static] |
Definition at line 208 of file chan_console.c.
Referenced by console_new(), load_module(), and unload_module().
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration.
Values shown here match the defaults shown in console.conf.sample
Definition at line 178 of file chan_console.c.
struct ast_jb_conf global_jbconf [static] |
Definition at line 185 of file chan_console.c.
struct console_pvt globals [static] |
Console pvt structure.
Currently, this is a singleton object. However, multiple instances will be needed when this module is updated for multiple device support.
Referenced by ast_str_retrieve_variable(), handle_show_globals(), load_config(), load_module(), pbx_builtin_clear_globals(), pbx_builtin_getvar_helper(), pbx_builtin_pushvar_helper(), pbx_builtin_setvar_helper(), set_active(), set_pvt_defaults(), store_config_core(), and unload_module().
ast_mutex_t globals_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Definition at line 164 of file chan_console.c.
Referenced by load_config(), load_module(), reload(), set_config(), set_pvt_defaults(), and unload_module().
struct ao2_container* pvts [static] |
Definition at line 166 of file chan_console.c.
Referenced by build_device(), cli_console_active(), cli_list_devices(), destroy_pvts(), find_pvt(), load_config(), load_module(), stop_streams(), and unload_module().