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