#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, int format, 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) |
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_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } |
static ast_rwlock_t | active_lock = 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 = ((ast_mutex_t) 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.
#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 1528 of file chan_console.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 1528 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 656 of file chan_console.c.
References ast_strdup, and console_pvt::overridecontext.
Referenced by cli_console_dial(), console_dial(), and console_transfer().
00657 { 00658 if (ext == NULL || ctx == NULL) 00659 return NULL; /* error */ 00660 00661 *ext = *ctx = NULL; 00662 00663 if (src && *src != '\0') 00664 *ext = ast_strdup(src); 00665 00666 if (*ext == NULL) 00667 return NULL; 00668 00669 if (!pvt->overridecontext) { 00670 /* parse from the right */ 00671 *ctx = strrchr(*ext, '@'); 00672 if (*ctx) 00673 *(*ctx)++ = '\0'; 00674 } 00675 00676 return *ext; 00677 }
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 1153 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.
01154 { 01155 struct console_pvt *pvt; 01156 01157 switch (cmd) { 01158 case CLI_INIT: 01159 e->command = "console active"; 01160 e->usage = 01161 "Usage: console active [device]\n" 01162 " If no device is specified. The active console device will be shown.\n" 01163 "Otherwise, the specified device will become the console device active for\n" 01164 "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 == e->args) { 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]))) { 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 1033 of file chan_console.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_indicate(), ast_queue_frame(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, f, ast_cli_args::fd, get_active_pvt(), console_pvt::hookstate, console_pvt::owner, unref_pvt(), and ast_cli_entry::usage.
01034 { 01035 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; 01036 struct console_pvt *pvt = get_active_pvt(); 01037 01038 switch (cmd) { 01039 case CLI_INIT: 01040 e->command = "console answer"; 01041 e->usage = 01042 "Usage: console answer\n" 01043 " Answers an incoming call on the console channel.\n"; 01044 return NULL; 01045 01046 case CLI_GENERATE: 01047 return NULL; /* no completion */ 01048 } 01049 01050 if (!pvt) { 01051 ast_cli(a->fd, "No console device is set as active\n"); 01052 return CLI_FAILURE; 01053 } 01054 01055 if (a->argc != e->args) { 01056 unref_pvt(pvt); 01057 return CLI_SHOWUSAGE; 01058 } 01059 01060 if (!pvt->owner) { 01061 ast_cli(a->fd, "No one is calling us\n"); 01062 unref_pvt(pvt); 01063 return CLI_FAILURE; 01064 } 01065 01066 pvt->hookstate = 1; 01067 01068 ast_indicate(pvt->owner, -1); 01069 01070 ast_queue_frame(pvt->owner, &f); 01071 01072 unref_pvt(pvt); 01073 01074 return CLI_SUCCESS; 01075 }
static char* cli_console_autoanswer | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 690 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.
00692 { 00693 struct console_pvt *pvt = get_active_pvt(); 00694 char *res = CLI_SUCCESS; 00695 00696 switch (cmd) { 00697 case CLI_INIT: 00698 e->command = "console set autoanswer [on|off]"; 00699 e->usage = 00700 "Usage: console set autoanswer [on|off]\n" 00701 " Enables or disables autoanswer feature. If used without\n" 00702 " argument, displays the current on/off status of autoanswer.\n" 00703 " The default value of autoanswer is in 'oss.conf'.\n"; 00704 return NULL; 00705 00706 case CLI_GENERATE: 00707 return NULL; 00708 } 00709 00710 if (!pvt) { 00711 ast_cli(a->fd, "No console device is set as active.\n"); 00712 return CLI_FAILURE; 00713 } 00714 00715 if (a->argc == e->args - 1) { 00716 ast_cli(a->fd, "Auto answer is %s.\n", pvt->autoanswer ? "on" : "off"); 00717 unref_pvt(pvt); 00718 return CLI_SUCCESS; 00719 } 00720 00721 if (a->argc != e->args) { 00722 unref_pvt(pvt); 00723 return CLI_SHOWUSAGE; 00724 } 00725 00726 if (!strcasecmp(a->argv[e->args-1], "on")) 00727 pvt->autoanswer = 1; 00728 else if (!strcasecmp(a->argv[e->args - 1], "off")) 00729 pvt->autoanswer = 0; 00730 else 00731 res = CLI_SHOWUSAGE; 00732 00733 unref_pvt(pvt); 00734 00735 return CLI_SUCCESS; 00736 }
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, s, 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, 0 }; 00801 00802 if (a->argc == e->args) { /* argument is mandatory here */ 00803 ast_cli(a->fd, "Already in a call. You can only dial digits until you hangup.\n"); 00804 unref_pvt(pvt); 00805 return CLI_FAILURE; 00806 } 00807 s = a->argv[e->args]; 00808 /* send the string one char at a time */ 00809 for (i = 0; i < strlen(s); i++) { 00810 f.subclass = s[i]; 00811 ast_queue_frame(pvt->owner, &f); 00812 } 00813 unref_pvt(pvt); 00814 return CLI_SUCCESS; 00815 } 00816 00817 /* if we have an argument split it into extension and context */ 00818 if (a->argc == e->args + 1) { 00819 char *ext = NULL, *con = NULL; 00820 s = ast_ext_ctx(pvt, a->argv[e->args], &ext, &con); 00821 ast_debug(1, "provided '%s', exten '%s' context '%s'\n", 00822 a->argv[e->args], mye, myc); 00823 mye = ext; 00824 myc = con; 00825 } 00826 00827 /* supply default values if needed */ 00828 if (ast_strlen_zero(mye)) 00829 mye = pvt->exten; 00830 if (ast_strlen_zero(myc)) 00831 myc = pvt->context; 00832 00833 if (ast_exists_extension(NULL, myc, mye, 1, NULL)) { 00834 console_pvt_lock(pvt); 00835 pvt->hookstate = 1; 00836 console_new(pvt, mye, myc, AST_STATE_RINGING); 00837 console_pvt_unlock(pvt); 00838 } else 00839 ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc); 00840 00841 if (s) 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 738 of file chan_console.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), AST_CONTROL_FLASH, AST_FRAME_CONTROL, ast_queue_frame(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, f, ast_cli_args::fd, get_active_pvt(), console_pvt::hookstate, console_pvt::owner, unref_pvt(), and ast_cli_entry::usage.
00739 { 00740 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH }; 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_frame(pvt->owner, &f); 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, s, unref_pvt(), ast_cli_entry::usage, V_BEGIN, and V_END.
00886 { 00887 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 1083 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(), buf, 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.
01084 { 01085 char buf[TEXT_SIZE]; 01086 struct console_pvt *pvt = get_active_pvt(); 01087 struct ast_frame f = { 01088 .frametype = AST_FRAME_TEXT, 01089 .data.ptr = buf, 01090 .src = "console_send_text", 01091 }; 01092 int len; 01093 01094 if (cmd == CLI_INIT) { 01095 e->command = "console send text"; 01096 e->usage = 01097 "Usage: console send text <message>\n" 01098 " Sends a text message for display on the remote terminal.\n"; 01099 return NULL; 01100 } else if (cmd == CLI_GENERATE) 01101 return NULL; 01102 01103 if (!pvt) { 01104 ast_cli(a->fd, "No console device is set as active\n"); 01105 return CLI_FAILURE; 01106 } 01107 01108 if (a->argc < e->args + 1) { 01109 unref_pvt(pvt); 01110 return CLI_SHOWUSAGE; 01111 } 01112 01113 if (!pvt->owner) { 01114 ast_cli(a->fd, "Not in a call\n"); 01115 unref_pvt(pvt); 01116 return CLI_FAILURE; 01117 } 01118 01119 ast_join(buf, sizeof(buf) - 1, a->argv + e->args); 01120 if (ast_strlen_zero(buf)) { 01121 unref_pvt(pvt); 01122 return CLI_SHOWUSAGE; 01123 } 01124 01125 len = strlen(buf); 01126 buf[len] = '\n'; 01127 f.datalen = len + 1; 01128 01129 ast_queue_frame(pvt->owner, &f); 01130 01131 unref_pvt(pvt); 01132 01133 return CLI_SUCCESS; 01134 }
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, num, 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 524 of file chan_console.c.
References ast_setstate(), AST_STATE_UP, ast_verb, start_stream(), ast_channel::tech_pvt, V_BEGIN, and V_END.
00525 { 00526 struct console_pvt *pvt = c->tech_pvt; 00527 00528 ast_verb(1, V_BEGIN "Call from Console has been Answered" V_END); 00529 00530 ast_setstate(c, AST_STATE_UP); 00531 00532 return start_stream(pvt); 00533 }
static int console_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 562 of file chan_console.c.
References AST_CONTROL_ANSWER, AST_CONTROL_RINGING, AST_FRAME_CONTROL, ast_indicate(), ast_queue_frame(), ast_verb, console_pvt::autoanswer, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, console_pvt_lock, console_pvt_unlock, f, console_pvt::hookstate, start_stream(), ast_channel::tech_pvt, V_BEGIN, and V_END.
00563 { 00564 struct ast_frame f = { 0, }; 00565 struct console_pvt *pvt = c->tech_pvt; 00566 00567 ast_verb(1, V_BEGIN "Call to device '%s' on console from '%s' <%s>" V_END, 00568 dest, c->cid.cid_name, c->cid.cid_num); 00569 00570 console_pvt_lock(pvt); 00571 00572 if (pvt->autoanswer) { 00573 pvt->hookstate = 1; 00574 console_pvt_unlock(pvt); 00575 ast_verb(1, V_BEGIN "Auto-answered" V_END); 00576 f.frametype = AST_FRAME_CONTROL; 00577 f.subclass = AST_CONTROL_ANSWER; 00578 } else { 00579 console_pvt_unlock(pvt); 00580 ast_verb(1, V_BEGIN "Type 'console answer' to answer, or use the 'autoanswer' option " 00581 "for future calls" V_END); 00582 f.frametype = AST_FRAME_CONTROL; 00583 f.subclass = AST_CONTROL_RINGING; 00584 ast_indicate(c, AST_CONTROL_RINGING); 00585 } 00586 00587 ast_queue_frame(c, &f); 00588 00589 return start_stream(pvt); 00590 }
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 636 of file chan_console.c.
References console_pvt::owner, and ast_channel::tech_pvt.
00637 { 00638 struct console_pvt *pvt = newchan->tech_pvt; 00639 00640 pvt->owner = newchan; 00641 00642 return 0; 00643 }
static int console_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 509 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.
00510 { 00511 struct console_pvt *pvt = c->tech_pvt; 00512 00513 ast_verb(1, V_BEGIN "Hangup on Console" V_END); 00514 00515 pvt->hookstate = 0; 00516 pvt->owner = NULL; 00517 stop_stream(pvt); 00518 00519 c->tech_pvt = unref_pvt(pvt); 00520 00521 return 0; 00522 }
static int console_indicate | ( | struct ast_channel * | chan, | |
int | cond, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 601 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, chan, LOG_WARNING, console_pvt::mohinterpret, ast_channel::name, ast_channel::tech_pvt, V_BEGIN, and V_END.
00602 { 00603 struct console_pvt *pvt = chan->tech_pvt; 00604 int res = 0; 00605 00606 switch (cond) { 00607 case AST_CONTROL_BUSY: 00608 case AST_CONTROL_CONGESTION: 00609 case AST_CONTROL_RINGING: 00610 case -1: 00611 res = -1; /* Ask for inband indications */ 00612 break; 00613 case AST_CONTROL_PROGRESS: 00614 case AST_CONTROL_PROCEEDING: 00615 case AST_CONTROL_VIDUPDATE: 00616 case AST_CONTROL_SRCUPDATE: 00617 break; 00618 case AST_CONTROL_HOLD: 00619 ast_verb(1, V_BEGIN "Console Has Been Placed on Hold" V_END); 00620 ast_moh_start(chan, data, pvt->mohinterpret); 00621 break; 00622 case AST_CONTROL_UNHOLD: 00623 ast_verb(1, V_BEGIN "Console Has Been Retrieved from Hold" V_END); 00624 ast_moh_stop(chan); 00625 break; 00626 default: 00627 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", 00628 cond, chan->name); 00629 /* The core will play inband indications for us if appropriate */ 00630 res = -1; 00631 } 00632 00633 return res; 00634 }
static struct ast_channel* console_new | ( | struct console_pvt * | pvt, | |
const char * | ext, | |||
const char * | ctx, | |||
int | state | |||
) | [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(), chan, 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, 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 555 of file chan_console.c.
References ast_debug, and ast_null_frame.
00556 { 00557 ast_debug(1, "I should not be called ...\n"); 00558 00559 return &ast_null_frame; 00560 }
static struct ast_channel * console_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Channel Technology Callbacks
Definition at line 451 of file chan_console.c.
References AST_CAUSE_BUSY, ast_log(), AST_STATE_DOWN, chan, console_new(), console_pvt_lock, console_pvt_unlock, find_pvt(), LOG_NOTICE, LOG_WARNING, console_pvt::owner, SUPPORTED_FORMATS, and unref_pvt().
00452 { 00453 int oldformat = format; 00454 struct ast_channel *chan = NULL; 00455 struct console_pvt *pvt; 00456 00457 if (!(pvt = find_pvt(data))) { 00458 ast_log(LOG_ERROR, "Console device '%s' not found\n", (char *) data); 00459 return NULL; 00460 } 00461 00462 format &= SUPPORTED_FORMATS; 00463 if (!format) { 00464 ast_log(LOG_NOTICE, "Channel requested with unsupported format(s): '%d'\n", oldformat); 00465 goto return_unref; 00466 } 00467 00468 if (pvt->owner) { 00469 ast_log(LOG_NOTICE, "Console channel already active!\n"); 00470 *cause = AST_CAUSE_BUSY; 00471 goto return_unref; 00472 } 00473 00474 console_pvt_lock(pvt); 00475 chan = console_new(pvt, NULL, NULL, AST_STATE_DOWN); 00476 console_pvt_unlock(pvt); 00477 00478 if (!chan) 00479 ast_log(LOG_WARNING, "Unable to create new Console channel!\n"); 00480 00481 return_unref: 00482 unref_pvt(pvt); 00483 00484 return chan; 00485 }
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 592 of file chan_console.c.
References chan, f, console_pvt::stream, and ast_channel::tech_pvt.
00593 { 00594 struct console_pvt *pvt = chan->tech_pvt; 00595 00596 Pa_WriteStream(pvt->stream, f->data.ptr, f->samples); 00597 00598 return 0; 00599 }
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 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 679 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().
00680 { 00681 struct console_pvt *pvt; 00682 00683 ast_rwlock_rdlock(&active_lock); 00684 pvt = ref_pvt(active_pvt); 00685 ast_rwlock_unlock(&active_lock); 00686 00687 return pvt; 00688 }
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_flags, 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 } 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 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 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 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 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 1136 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().
01137 { 01138 if (pvt == &globals) { 01139 ast_log(LOG_ERROR, "active is only valid as a per-device setting\n"); 01140 return; 01141 } 01142 01143 if (!ast_true(value)) 01144 return; 01145 01146 ast_rwlock_wrlock(&active_lock); 01147 if (active_pvt) 01148 unref_pvt(active_pvt); 01149 active_pvt = ref_pvt(pvt); 01150 ast_rwlock_unlock(&active_lock); 01151 }
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, cid_name, cid_num, context, exten, globals, globals_lock, language, mohinterpret, console_pvt::overridecontext, 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 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 1269 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().
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 261 of file chan_console.c.
References AST_FORMAT_SLINEAR16, AST_FRAME_VOICE, ast_queue_frame(), buf, 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 = 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_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 1528 of file chan_console.c.
ast_rwlock_t active_lock = 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 1528 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.
ast_mutex_t globals_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
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(), pri_create_trunkgroup(), setup_dahdi(), stop_streams(), and unload_module().