Cross-platform console channel driver. More...
#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... | |
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 |
|
| |
| #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) |
Cross-platform console channel driver.
To install portaudio v19 from svn, check it out using the following command:
Definition in file chan_console.c.
| #define console_pvt_lock | ( | pvt | ) | ao2_lock(pvt) |
lock a console_pvt struct
Definition at line 223 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 226 of file chan_console.c.
Referenced by build_device(), cli_console_active(), cli_console_dial(), cli_list_devices(), console_call(), console_request(), start_stream(), and stop_stream().
| #define INPUT_CHANNELS 1 |
| #define NUM_PVT_BUCKETS 7 |
Definition at line 166 of file chan_console.c.
Referenced by load_module().
| #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 203 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 1519 of file chan_console.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 1519 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 648 of file chan_console.c.
References ast_strdup, and console_pvt::overridecontext.
Referenced by cli_console_dial().
00649 { 00650 if (ext == NULL || ctx == NULL) 00651 return NULL; /* error */ 00652 00653 *ext = *ctx = NULL; 00654 00655 if (src && *src != '\0') 00656 *ext = ast_strdup(src); 00657 00658 if (*ext == NULL) 00659 return NULL; 00660 00661 if (!pvt->overridecontext) { 00662 /* parse from the right */ 00663 *ctx = strrchr(*ext, '@'); 00664 if (*ctx) 00665 *(*ctx)++ = '\0'; 00666 } 00667 00668 return *ext; 00669 }
| static void build_device | ( | struct ast_config * | cfg, | |
| const char * | name | |||
| ) | [static] |
Definition at line 1324 of file chan_console.c.
References ao2_alloc, ao2_link, ast_variable_browse(), console_pvt_lock, console_pvt_unlock, console_pvt::destroy, find_pvt(), init_pvt(), ast_variable::name, ast_variable::next, pvt_destructor(), set_pvt_defaults(), store_config_core(), unref_pvt(), and ast_variable::value.
Referenced by load_config().
01325 { 01326 struct ast_variable *v; 01327 struct console_pvt *pvt; 01328 int new = 0; 01329 01330 if ((pvt = find_pvt(name))) { 01331 console_pvt_lock(pvt); 01332 set_pvt_defaults(pvt); 01333 pvt->destroy = 0; 01334 } else { 01335 if (!(pvt = ao2_alloc(sizeof(*pvt), pvt_destructor))) 01336 return; 01337 init_pvt(pvt, name); 01338 set_pvt_defaults(pvt); 01339 new = 1; 01340 } 01341 01342 for (v = ast_variable_browse(cfg, name); v; v = v->next) 01343 store_config_core(pvt, v->name, v->value); 01344 01345 if (new) 01346 ao2_link(pvts, pvt); 01347 else 01348 console_pvt_unlock(pvt); 01349 01350 unref_pvt(pvt); 01351 }
| static char* cli_console_active | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1145 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, set_active(), unref_pvt(), ast_cli_entry::usage, and ast_cli_args::word.
01146 { 01147 struct console_pvt *pvt; 01148 01149 switch (cmd) { 01150 case CLI_INIT: 01151 e->command = "console active"; 01152 e->usage = 01153 "Usage: console active [device]\n" 01154 " If no device is specified. The active console device will be shown.\n" 01155 "Otherwise, the specified device will become the console device active for\n" 01156 "the Asterisk CLI.\n"; 01157 return NULL; 01158 case CLI_GENERATE: 01159 if (a->pos == e->args) { 01160 struct ao2_iterator i; 01161 int x = 0; 01162 char *res = NULL; 01163 i = ao2_iterator_init(pvts, 0); 01164 while ((pvt = ao2_iterator_next(&i))) { 01165 if (++x > a->n && !strncasecmp(pvt->name, a->word, strlen(a->word))) 01166 res = ast_strdup(pvt->name); 01167 unref_pvt(pvt); 01168 if (res) { 01169 ao2_iterator_destroy(&i); 01170 return res; 01171 } 01172 } 01173 ao2_iterator_destroy(&i); 01174 } 01175 return NULL; 01176 } 01177 01178 if (a->argc < e->args) 01179 return CLI_SHOWUSAGE; 01180 01181 if (a->argc == e->args) { 01182 pvt = get_active_pvt(); 01183 01184 if (!pvt) 01185 ast_cli(a->fd, "No device is currently set as the active console device.\n"); 01186 else { 01187 console_pvt_lock(pvt); 01188 ast_cli(a->fd, "The active console device is '%s'.\n", pvt->name); 01189 console_pvt_unlock(pvt); 01190 pvt = unref_pvt(pvt); 01191 } 01192 01193 return CLI_SUCCESS; 01194 } 01195 01196 if (!(pvt = find_pvt(a->argv[e->args]))) { 01197 ast_cli(a->fd, "Could not find a device called '%s'.\n", a->argv[e->args]); 01198 return CLI_FAILURE; 01199 } 01200 01201 set_active(pvt, "yes"); 01202 01203 console_pvt_lock(pvt); 01204 ast_cli(a->fd, "The active console device has been set to '%s'\n", pvt->name); 01205 console_pvt_unlock(pvt); 01206 01207 unref_pvt(pvt); 01208 01209 return CLI_SUCCESS; 01210 }
| 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 1025 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, ast_cli_args::fd, get_active_pvt(), console_pvt::hookstate, console_pvt::owner, unref_pvt(), and ast_cli_entry::usage.
01026 { 01027 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; 01028 struct console_pvt *pvt = get_active_pvt(); 01029 01030 switch (cmd) { 01031 case CLI_INIT: 01032 e->command = "console answer"; 01033 e->usage = 01034 "Usage: console answer\n" 01035 " Answers an incoming call on the console channel.\n"; 01036 return NULL; 01037 01038 case CLI_GENERATE: 01039 return NULL; /* no completion */ 01040 } 01041 01042 if (!pvt) { 01043 ast_cli(a->fd, "No console device is set as active\n"); 01044 return CLI_FAILURE; 01045 } 01046 01047 if (a->argc != e->args) { 01048 unref_pvt(pvt); 01049 return CLI_SHOWUSAGE; 01050 } 01051 01052 if (!pvt->owner) { 01053 ast_cli(a->fd, "No one is calling us\n"); 01054 unref_pvt(pvt); 01055 return CLI_FAILURE; 01056 } 01057 01058 pvt->hookstate = 1; 01059 01060 ast_indicate(pvt->owner, -1); 01061 01062 ast_queue_frame(pvt->owner, &f); 01063 01064 unref_pvt(pvt); 01065 01066 return CLI_SUCCESS; 01067 }
| static char* cli_console_autoanswer | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 682 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.
00684 { 00685 struct console_pvt *pvt = get_active_pvt(); 00686 char *res = CLI_SUCCESS; 00687 00688 switch (cmd) { 00689 case CLI_INIT: 00690 e->command = "console set autoanswer [on|off]"; 00691 e->usage = 00692 "Usage: console set autoanswer [on|off]\n" 00693 " Enables or disables autoanswer feature. If used without\n" 00694 " argument, displays the current on/off status of autoanswer.\n" 00695 " The default value of autoanswer is in 'oss.conf'.\n"; 00696 return NULL; 00697 00698 case CLI_GENERATE: 00699 return NULL; 00700 } 00701 00702 if (!pvt) { 00703 ast_cli(a->fd, "No console device is set as active.\n"); 00704 return CLI_FAILURE; 00705 } 00706 00707 if (a->argc == e->args - 1) { 00708 ast_cli(a->fd, "Auto answer is %s.\n", pvt->autoanswer ? "on" : "off"); 00709 unref_pvt(pvt); 00710 return CLI_SUCCESS; 00711 } 00712 00713 if (a->argc != e->args) { 00714 unref_pvt(pvt); 00715 return CLI_SHOWUSAGE; 00716 } 00717 00718 if (!strcasecmp(a->argv[e->args-1], "on")) 00719 pvt->autoanswer = 1; 00720 else if (!strcasecmp(a->argv[e->args - 1], "off")) 00721 pvt->autoanswer = 0; 00722 else 00723 res = CLI_SHOWUSAGE; 00724 00725 unref_pvt(pvt); 00726 00727 return CLI_SUCCESS; 00728 }
| static char* cli_console_dial | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 767 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, ast_cli_args::fd, free, get_active_pvt(), console_pvt::hookstate, console_pvt::owner, s, ast_frame::subclass, unref_pvt(), and ast_cli_entry::usage.
00768 { 00769 char *s = NULL; 00770 const char *mye = NULL, *myc = NULL; 00771 struct console_pvt *pvt = get_active_pvt(); 00772 00773 if (cmd == CLI_INIT) { 00774 e->command = "console dial"; 00775 e->usage = 00776 "Usage: console dial [extension[@context]]\n" 00777 " Dials a given extension (and context if specified)\n"; 00778 return NULL; 00779 } else if (cmd == CLI_GENERATE) 00780 return NULL; 00781 00782 if (!pvt) { 00783 ast_cli(a->fd, "No console device is currently set as active\n"); 00784 return CLI_FAILURE; 00785 } 00786 00787 if (a->argc > e->args + 1) 00788 return CLI_SHOWUSAGE; 00789 00790 if (pvt->owner) { /* already in a call */ 00791 int i; 00792 struct ast_frame f = { AST_FRAME_DTMF, 0 }; 00793 00794 if (a->argc == e->args) { /* argument is mandatory here */ 00795 ast_cli(a->fd, "Already in a call. You can only dial digits until you hangup.\n"); 00796 unref_pvt(pvt); 00797 return CLI_FAILURE; 00798 } 00799 s = a->argv[e->args]; 00800 /* send the string one char at a time */ 00801 for (i = 0; i < strlen(s); i++) { 00802 f.subclass = s[i]; 00803 ast_queue_frame(pvt->owner, &f); 00804 } 00805 unref_pvt(pvt); 00806 return CLI_SUCCESS; 00807 } 00808 00809 /* if we have an argument split it into extension and context */ 00810 if (a->argc == e->args + 1) { 00811 char *ext = NULL, *con = NULL; 00812 s = ast_ext_ctx(pvt, a->argv[e->args], &ext, &con); 00813 ast_debug(1, "provided '%s', exten '%s' context '%s'\n", 00814 a->argv[e->args], mye, myc); 00815 mye = ext; 00816 myc = con; 00817 } 00818 00819 /* supply default values if needed */ 00820 if (ast_strlen_zero(mye)) 00821 mye = pvt->exten; 00822 if (ast_strlen_zero(myc)) 00823 myc = pvt->context; 00824 00825 if (ast_exists_extension(NULL, myc, mye, 1, NULL)) { 00826 console_pvt_lock(pvt); 00827 pvt->hookstate = 1; 00828 console_new(pvt, mye, myc, AST_STATE_RINGING); 00829 console_pvt_unlock(pvt); 00830 } else 00831 ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc); 00832 00833 if (s) 00834 free(s); 00835 00836 unref_pvt(pvt); 00837 00838 return CLI_SUCCESS; 00839 }
| static char* cli_console_flash | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 730 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, ast_cli_args::fd, get_active_pvt(), console_pvt::hookstate, console_pvt::owner, unref_pvt(), and ast_cli_entry::usage.
00731 { 00732 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH }; 00733 struct console_pvt *pvt = get_active_pvt(); 00734 00735 if (cmd == CLI_INIT) { 00736 e->command = "console flash"; 00737 e->usage = 00738 "Usage: console flash\n" 00739 " Flashes the call currently placed on the console.\n"; 00740 return NULL; 00741 } else if (cmd == CLI_GENERATE) 00742 return NULL; 00743 00744 if (!pvt) { 00745 ast_cli(a->fd, "No console device is set as active\n"); 00746 return CLI_FAILURE; 00747 } 00748 00749 if (a->argc != e->args) 00750 return CLI_SHOWUSAGE; 00751 00752 if (!pvt->owner) { 00753 ast_cli(a->fd, "No call to flash\n"); 00754 unref_pvt(pvt); 00755 return CLI_FAILURE; 00756 } 00757 00758 pvt->hookstate = 0; 00759 00760 ast_queue_frame(pvt->owner, &f); 00761 00762 unref_pvt(pvt); 00763 00764 return CLI_SUCCESS; 00765 }
| static char* cli_console_hangup | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 841 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.
00842 { 00843 struct console_pvt *pvt = get_active_pvt(); 00844 00845 if (cmd == CLI_INIT) { 00846 e->command = "console hangup"; 00847 e->usage = 00848 "Usage: console hangup\n" 00849 " Hangs up any call currently placed on the console.\n"; 00850 return NULL; 00851 } else if (cmd == CLI_GENERATE) 00852 return NULL; 00853 00854 if (!pvt) { 00855 ast_cli(a->fd, "No console device is set as active\n"); 00856 return CLI_FAILURE; 00857 } 00858 00859 if (a->argc != e->args) 00860 return CLI_SHOWUSAGE; 00861 00862 if (!pvt->owner && !pvt->hookstate) { 00863 ast_cli(a->fd, "No call to hang up\n"); 00864 unref_pvt(pvt); 00865 return CLI_FAILURE; 00866 } 00867 00868 pvt->hookstate = 0; 00869 if (pvt->owner) 00870 ast_queue_hangup(pvt->owner); 00871 00872 unref_pvt(pvt); 00873 00874 return CLI_SUCCESS; 00875 }
| static char* cli_console_mute | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 877 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.
00878 { 00879 char *s; 00880 struct console_pvt *pvt = get_active_pvt(); 00881 char *res = CLI_SUCCESS; 00882 00883 if (cmd == CLI_INIT) { 00884 e->command = "console {mute|unmute}"; 00885 e->usage = 00886 "Usage: console {mute|unmute}\n" 00887 " Mute/unmute the microphone.\n"; 00888 return NULL; 00889 } else if (cmd == CLI_GENERATE) 00890 return NULL; 00891 00892 if (!pvt) { 00893 ast_cli(a->fd, "No console device is set as active\n"); 00894 return CLI_FAILURE; 00895 } 00896 00897 if (a->argc != e->args) 00898 return CLI_SHOWUSAGE; 00899 00900 s = a->argv[e->args-1]; 00901 if (!strcasecmp(s, "mute")) 00902 pvt->muted = 1; 00903 else if (!strcasecmp(s, "unmute")) 00904 pvt->muted = 0; 00905 else 00906 res = CLI_SHOWUSAGE; 00907 00908 ast_verb(1, V_BEGIN "The Console is now %s" V_END, 00909 pvt->muted ? "Muted" : "Unmuted"); 00910 00911 unref_pvt(pvt); 00912 00913 return res; 00914 }
| 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 1075 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, ast_frame::datalen, ast_cli_args::fd, ast_frame::frametype, get_active_pvt(), len(), console_pvt::owner, TEXT_SIZE, unref_pvt(), and ast_cli_entry::usage.
01076 { 01077 char buf[TEXT_SIZE]; 01078 struct console_pvt *pvt = get_active_pvt(); 01079 struct ast_frame f = { 01080 .frametype = AST_FRAME_TEXT, 01081 .data.ptr = buf, 01082 .src = "console_send_text", 01083 }; 01084 int len; 01085 01086 if (cmd == CLI_INIT) { 01087 e->command = "console send text"; 01088 e->usage = 01089 "Usage: console send text <message>\n" 01090 " Sends a text message for display on the remote terminal.\n"; 01091 return NULL; 01092 } else if (cmd == CLI_GENERATE) 01093 return NULL; 01094 01095 if (!pvt) { 01096 ast_cli(a->fd, "No console device is set as active\n"); 01097 return CLI_FAILURE; 01098 } 01099 01100 if (a->argc < e->args + 1) { 01101 unref_pvt(pvt); 01102 return CLI_SHOWUSAGE; 01103 } 01104 01105 if (!pvt->owner) { 01106 ast_cli(a->fd, "Not in a call\n"); 01107 unref_pvt(pvt); 01108 return CLI_FAILURE; 01109 } 01110 01111 ast_join(buf, sizeof(buf) - 1, a->argv + e->args); 01112 if (ast_strlen_zero(buf)) { 01113 unref_pvt(pvt); 01114 return CLI_SHOWUSAGE; 01115 } 01116 01117 len = strlen(buf); 01118 buf[len] = '\n'; 01119 f.datalen = len + 1; 01120 01121 ast_queue_frame(pvt->owner, &f); 01122 01123 unref_pvt(pvt); 01124 01125 return CLI_SUCCESS; 01126 }
| static char* cli_list_available | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 916 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.
00917 { 00918 PaDeviceIndex idx, num, def_input, def_output; 00919 00920 if (cmd == CLI_INIT) { 00921 e->command = "console list available"; 00922 e->usage = 00923 "Usage: console list available\n" 00924 " List all available devices.\n"; 00925 return NULL; 00926 } else if (cmd == CLI_GENERATE) 00927 return NULL; 00928 00929 if (a->argc != e->args) 00930 return CLI_SHOWUSAGE; 00931 00932 ast_cli(a->fd, "\n" 00933 "=============================================================\n" 00934 "=== Available Devices =======================================\n" 00935 "=============================================================\n" 00936 "===\n"); 00937 00938 num = Pa_GetDeviceCount(); 00939 if (!num) { 00940 ast_cli(a->fd, "(None)\n"); 00941 return CLI_SUCCESS; 00942 } 00943 00944 def_input = Pa_GetDefaultInputDevice(); 00945 def_output = Pa_GetDefaultOutputDevice(); 00946 for (idx = 0; idx < num; idx++) { 00947 const PaDeviceInfo *dev = Pa_GetDeviceInfo(idx); 00948 if (!dev) 00949 continue; 00950 ast_cli(a->fd, "=== ---------------------------------------------------------\n" 00951 "=== Device Name: %s\n", dev->name); 00952 if (dev->maxInputChannels) 00953 ast_cli(a->fd, "=== ---> %sInput Device\n", (idx == def_input) ? "Default " : ""); 00954 if (dev->maxOutputChannels) 00955 ast_cli(a->fd, "=== ---> %sOutput Device\n", (idx == def_output) ? "Default " : ""); 00956 ast_cli(a->fd, "=== ---------------------------------------------------------\n===\n"); 00957 } 00958 00959 ast_cli(a->fd, "=============================================================\n\n"); 00960 00961 return CLI_SUCCESS; 00962 }
| static char* cli_list_devices | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 964 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(), console_pvt::autoanswer, console_pvt::cid_name, console_pvt::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, console_pvt_lock, console_pvt_unlock, console_pvt::context, console_pvt::exten, ast_cli_args::fd, console_pvt::input_device, console_pvt::language, console_pvt::mohinterpret, console_pvt::muted, console_pvt::name, console_pvt::output_device, console_pvt::overridecontext, console_pvt::parkinglot, unref_pvt(), and ast_cli_entry::usage.
00965 { 00966 struct ao2_iterator i; 00967 struct console_pvt *pvt; 00968 00969 if (cmd == CLI_INIT) { 00970 e->command = "console list devices"; 00971 e->usage = 00972 "Usage: console list devices\n" 00973 " List all configured devices.\n"; 00974 return NULL; 00975 } else if (cmd == CLI_GENERATE) 00976 return NULL; 00977 00978 if (a->argc != e->args) 00979 return CLI_SHOWUSAGE; 00980 00981 ast_cli(a->fd, "\n" 00982 "=============================================================\n" 00983 "=== Configured Devices ======================================\n" 00984 "=============================================================\n" 00985 "===\n"); 00986 00987 i = ao2_iterator_init(pvts, 0); 00988 while ((pvt = ao2_iterator_next(&i))) { 00989 console_pvt_lock(pvt); 00990 00991 ast_cli(a->fd, "=== ---------------------------------------------------------\n" 00992 "=== Device Name: %s\n" 00993 "=== ---> Active: %s\n" 00994 "=== ---> Input Device: %s\n" 00995 "=== ---> Output Device: %s\n" 00996 "=== ---> Context: %s\n" 00997 "=== ---> Extension: %s\n" 00998 "=== ---> CallerID Num: %s\n" 00999 "=== ---> CallerID Name: %s\n" 01000 "=== ---> MOH Interpret: %s\n" 01001 "=== ---> Language: %s\n" 01002 "=== ---> Parkinglot: %s\n" 01003 "=== ---> Muted: %s\n" 01004 "=== ---> Auto-Answer: %s\n" 01005 "=== ---> Override Context: %s\n" 01006 "=== ---------------------------------------------------------\n===\n", 01007 pvt->name, (pvt == active_pvt) ? "Yes" : "No", 01008 pvt->input_device, pvt->output_device, pvt->context, 01009 pvt->exten, pvt->cid_num, pvt->cid_name, pvt->mohinterpret, 01010 pvt->language, pvt->parkinglot, pvt->muted ? "Yes" : "No", pvt->autoanswer ? "Yes" : "No", 01011 pvt->overridecontext ? "Yes" : "No"); 01012 01013 console_pvt_unlock(pvt); 01014 unref_pvt(pvt); 01015 } 01016 ao2_iterator_destroy(&i); 01017 01018 ast_cli(a->fd, "=============================================================\n\n"); 01019 01020 return CLI_SUCCESS; 01021 }
| static int console_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 516 of file chan_console.c.
References ast_setstate(), AST_STATE_UP, ast_verb, start_stream(), ast_channel::tech_pvt, V_BEGIN, and V_END.
00517 { 00518 struct console_pvt *pvt = c->tech_pvt; 00519 00520 ast_verb(1, V_BEGIN "Call from Console has been Answered" V_END); 00521 00522 ast_setstate(c, AST_STATE_UP); 00523 00524 return start_stream(pvt); 00525 }
| static int console_call | ( | struct ast_channel * | c, | |
| char * | dest, | |||
| int | timeout | |||
| ) | [static] |
Definition at line 554 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, ast_frame::frametype, console_pvt::hookstate, start_stream(), ast_frame::subclass, ast_channel::tech_pvt, V_BEGIN, and V_END.
00555 { 00556 struct ast_frame f = { 0, }; 00557 struct console_pvt *pvt = c->tech_pvt; 00558 00559 ast_verb(1, V_BEGIN "Call to device '%s' on console from '%s' <%s>" V_END, 00560 dest, c->cid.cid_name, c->cid.cid_num); 00561 00562 console_pvt_lock(pvt); 00563 00564 if (pvt->autoanswer) { 00565 pvt->hookstate = 1; 00566 console_pvt_unlock(pvt); 00567 ast_verb(1, V_BEGIN "Auto-answered" V_END); 00568 f.frametype = AST_FRAME_CONTROL; 00569 f.subclass = AST_CONTROL_ANSWER; 00570 } else { 00571 console_pvt_unlock(pvt); 00572 ast_verb(1, V_BEGIN "Type 'console answer' to answer, or use the 'autoanswer' option " 00573 "for future calls" V_END); 00574 f.frametype = AST_FRAME_CONTROL; 00575 f.subclass = AST_CONTROL_RINGING; 00576 ast_indicate(c, AST_CONTROL_RINGING); 00577 } 00578 00579 ast_queue_frame(c, &f); 00580 00581 return start_stream(pvt); 00582 }
| 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 628 of file chan_console.c.
References console_pvt::owner, and ast_channel::tech_pvt.
00629 { 00630 struct console_pvt *pvt = newchan->tech_pvt; 00631 00632 pvt->owner = newchan; 00633 00634 return 0; 00635 }
| static int console_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 501 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.
00502 { 00503 struct console_pvt *pvt = c->tech_pvt; 00504 00505 ast_verb(1, V_BEGIN "Hangup on Console" V_END); 00506 00507 pvt->hookstate = 0; 00508 pvt->owner = NULL; 00509 stop_stream(pvt); 00510 00511 c->tech_pvt = unref_pvt(pvt); 00512 00513 return 0; 00514 }
| static int console_indicate | ( | struct ast_channel * | chan, | |
| int | cond, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Definition at line 593 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::tech_pvt, V_BEGIN, and V_END.
00594 { 00595 struct console_pvt *pvt = chan->tech_pvt; 00596 int res = 0; 00597 00598 switch (cond) { 00599 case AST_CONTROL_BUSY: 00600 case AST_CONTROL_CONGESTION: 00601 case AST_CONTROL_RINGING: 00602 case -1: 00603 res = -1; /* Ask for inband indications */ 00604 break; 00605 case AST_CONTROL_PROGRESS: 00606 case AST_CONTROL_PROCEEDING: 00607 case AST_CONTROL_VIDUPDATE: 00608 case AST_CONTROL_SRCUPDATE: 00609 break; 00610 case AST_CONTROL_HOLD: 00611 ast_verb(1, V_BEGIN "Console Has Been Placed on Hold" V_END); 00612 ast_moh_start(chan, data, pvt->mohinterpret); 00613 break; 00614 case AST_CONTROL_UNHOLD: 00615 ast_verb(1, V_BEGIN "Console Has Been Retrieved from Hold" V_END); 00616 ast_moh_stop(chan); 00617 break; 00618 default: 00619 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", 00620 cond, chan->name); 00621 /* The core will play inband indications for us if appropriate */ 00622 res = -1; 00623 } 00624 00625 return res; 00626 }
| static struct ast_channel* console_new | ( | struct console_pvt * | pvt, | |
| const char * | ext, | |||
| const char * | ctx, | |||
| int | state | |||
| ) | [static, read] |
Definition at line 409 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, global_jbconf, ast_channel::hangupcause, 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().
00410 { 00411 struct ast_channel *chan; 00412 00413 if (!(chan = ast_channel_alloc(1, state, pvt->cid_num, pvt->cid_name, NULL, 00414 ext, ctx, 0, "Console/%s", pvt->name))) { 00415 return NULL; 00416 } 00417 00418 chan->tech = &console_tech; 00419 chan->nativeformats = AST_FORMAT_SLINEAR16; 00420 chan->readformat = AST_FORMAT_SLINEAR16; 00421 chan->writeformat = AST_FORMAT_SLINEAR16; 00422 chan->tech_pvt = ref_pvt(pvt); 00423 00424 pvt->owner = chan; 00425 00426 if (!ast_strlen_zero(pvt->language)) 00427 ast_string_field_set(chan, language, pvt->language); 00428 00429 ast_jb_configure(chan, &global_jbconf); 00430 00431 if (state != AST_STATE_DOWN) { 00432 if (ast_pbx_start(chan)) { 00433 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 00434 ast_hangup(chan); 00435 chan = NULL; 00436 } else 00437 start_stream(pvt); 00438 } 00439 00440 return chan; 00441 }
| static struct ast_frame * console_read | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 547 of file chan_console.c.
References ast_debug, and ast_null_frame.
00548 { 00549 ast_debug(1, "I should not be called ...\n"); 00550 00551 return &ast_null_frame; 00552 }
| static struct ast_channel * console_request | ( | const char * | type, | |
| int | format, | |||
| void * | data, | |||
| int * | cause | |||
| ) | [static, read] |
Channel Technology Callbacks
Definition at line 443 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_ERROR, LOG_NOTICE, LOG_WARNING, console_pvt::owner, SUPPORTED_FORMATS, and unref_pvt().
00444 { 00445 int oldformat = format; 00446 struct ast_channel *chan = NULL; 00447 struct console_pvt *pvt; 00448 00449 if (!(pvt = find_pvt(data))) { 00450 ast_log(LOG_ERROR, "Console device '%s' not found\n", (char *) data); 00451 return NULL; 00452 } 00453 00454 format &= SUPPORTED_FORMATS; 00455 if (!format) { 00456 ast_log(LOG_NOTICE, "Channel requested with unsupported format(s): '%d'\n", oldformat); 00457 goto return_unref; 00458 } 00459 00460 if (pvt->owner) { 00461 ast_log(LOG_NOTICE, "Console channel already active!\n"); 00462 *cause = AST_CAUSE_BUSY; 00463 goto return_unref; 00464 } 00465 00466 console_pvt_lock(pvt); 00467 chan = console_new(pvt, NULL, NULL, AST_STATE_DOWN); 00468 console_pvt_unlock(pvt); 00469 00470 if (!chan) 00471 ast_log(LOG_WARNING, "Unable to create new Console channel!\n"); 00472 00473 return_unref: 00474 unref_pvt(pvt); 00475 00476 return chan; 00477 }
| 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 584 of file chan_console.c.
References ast_frame::data, ast_frame::ptr, ast_frame::samples, console_pvt::stream, and ast_channel::tech_pvt.
| static void destroy_pvts | ( | void | ) | [static] |
Definition at line 1360 of file chan_console.c.
References active_lock, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_unlink, ast_rwlock_unlock(), ast_rwlock_wrlock(), console_pvt::destroy, and unref_pvt().
Referenced by load_config().
01361 { 01362 struct ao2_iterator i; 01363 struct console_pvt *pvt; 01364 01365 i = ao2_iterator_init(pvts, 0); 01366 while ((pvt = ao2_iterator_next(&i))) { 01367 if (pvt->destroy) { 01368 ao2_unlink(pvts, pvt); 01369 ast_rwlock_wrlock(&active_lock); 01370 if (active_pvt == pvt) 01371 active_pvt = unref_pvt(pvt); 01372 ast_rwlock_unlock(&active_lock); 01373 } 01374 unref_pvt(pvt); 01375 } 01376 ao2_iterator_destroy(&i); 01377 }
| static struct console_pvt* find_pvt | ( | const char * | name | ) | [static, read] |
Definition at line 241 of file chan_console.c.
References ao2_find, console_pvt::name, and OBJ_POINTER.
Referenced by build_device(), cli_console_active(), and console_request().
00242 { 00243 struct console_pvt tmp_pvt = { 00244 .name = name, 00245 }; 00246 00247 return ao2_find(pvts, &tmp_pvt, OBJ_POINTER); 00248 }
| static struct console_pvt* get_active_pvt | ( | void | ) | [static, read] |
Definition at line 671 of file chan_console.c.
References active_lock, 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().
00672 { 00673 struct console_pvt *pvt; 00674 00675 ast_rwlock_rdlock(&active_lock); 00676 pvt = ref_pvt(active_pvt); 00677 ast_rwlock_unlock(&active_lock); 00678 00679 return pvt; 00680 }
| static int init_pvt | ( | struct console_pvt * | pvt, | |
| const char * | name | |||
| ) | [static] |
Definition at line 1312 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().
01313 { 01314 pvt->thread = AST_PTHREADT_NULL; 01315 01316 if (ast_string_field_init(pvt, 32)) 01317 return -1; 01318 01319 ast_string_field_set(pvt, name, S_OR(name, "")); 01320 01321 return 0; 01322 }
| 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 1385 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(), context, destroy_pvts(), global_jbconf, globals, globals_lock, LOG_NOTICE, ast_variable::name, ast_variable::next, OBJ_NODATA, pvt_mark_destroy_cb(), set_pvt_defaults(), store_config_core(), and ast_variable::value.
Referenced by load_module(), and reload().
01386 { 01387 struct ast_config *cfg; 01388 struct ast_variable *v; 01389 struct ast_flags config_flags = { 0 }; 01390 char *context = NULL; 01391 01392 /* default values */ 01393 memcpy(&global_jbconf, &default_jbconf, sizeof(global_jbconf)); 01394 ast_mutex_lock(&globals_lock); 01395 set_pvt_defaults(&globals); 01396 ast_mutex_unlock(&globals_lock); 01397 01398 if (!(cfg = ast_config_load(config_file, config_flags))) { 01399 ast_log(LOG_NOTICE, "Unable to open configuration file %s!\n", config_file); 01400 return -1; 01401 } 01402 01403 ao2_callback(pvts, OBJ_NODATA, pvt_mark_destroy_cb, NULL); 01404 01405 ast_mutex_lock(&globals_lock); 01406 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) 01407 store_config_core(&globals, v->name, v->value); 01408 ast_mutex_unlock(&globals_lock); 01409 01410 while ((context = ast_category_browse(cfg, context))) { 01411 if (strcasecmp(context, "general")) 01412 build_device(cfg, context); 01413 } 01414 01415 ast_config_destroy(cfg); 01416 01417 destroy_pvts(); 01418 01419 return 0; 01420 }
| static int load_module | ( | void | ) | [static] |
Definition at line 1467 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, globals, init_pvt(), load_config(), LOG_ERROR, LOG_WARNING, NUM_PVT_BUCKETS, pvt_cmp_cb(), pvt_destructor(), and pvt_hash_cb().
01468 { 01469 PaError res; 01470 01471 init_pvt(&globals, NULL); 01472 01473 if (!(pvts = ao2_container_alloc(NUM_PVT_BUCKETS, pvt_hash_cb, pvt_cmp_cb))) 01474 goto return_error; 01475 01476 if (load_config(0)) 01477 goto return_error; 01478 01479 res = Pa_Initialize(); 01480 if (res != paNoError) { 01481 ast_log(LOG_WARNING, "Failed to initialize audio system - (%d) %s\n", 01482 res, Pa_GetErrorText(res)); 01483 goto return_error_pa_init; 01484 } 01485 01486 if (ast_channel_register(&console_tech)) { 01487 ast_log(LOG_ERROR, "Unable to register channel type 'Console'\n"); 01488 goto return_error_chan_reg; 01489 } 01490 01491 if (ast_cli_register_multiple(cli_console, ARRAY_LEN(cli_console))) 01492 goto return_error_cli_reg; 01493 01494 return AST_MODULE_LOAD_SUCCESS; 01495 01496 return_error_cli_reg: 01497 ast_cli_unregister_multiple(cli_console, ARRAY_LEN(cli_console)); 01498 return_error_chan_reg: 01499 ast_channel_unregister(&console_tech); 01500 return_error_pa_init: 01501 Pa_Terminate(); 01502 return_error: 01503 if (pvts) 01504 ao2_ref(pvts, -1); 01505 pvt_destructor(&globals); 01506 01507 return AST_MODULE_LOAD_DECLINE; 01508 }
| static int open_stream | ( | struct console_pvt * | pvt | ) | [static] |
Definition at line 286 of file chan_console.c.
References ast_log(), INPUT_CHANNELS, console_pvt::input_device, LOG_ERROR, console_pvt::name, NUM_SAMPLES, OUTPUT_CHANNELS, console_pvt::output_device, SAMPLE_RATE, and console_pvt::stream.
Referenced by start_stream().
00287 { 00288 int res = paInternalError; 00289 00290 if (!strcasecmp(pvt->input_device, "default") && 00291 !strcasecmp(pvt->output_device, "default")) { 00292 res = Pa_OpenDefaultStream(&pvt->stream, INPUT_CHANNELS, OUTPUT_CHANNELS, 00293 paInt16, SAMPLE_RATE, NUM_SAMPLES, NULL, NULL); 00294 } else { 00295 PaStreamParameters input_params = { 00296 .channelCount = 1, 00297 .sampleFormat = paInt16, 00298 .suggestedLatency = (1.0 / 50.0), /* 20 ms */ 00299 .device = paNoDevice, 00300 }; 00301 PaStreamParameters output_params = { 00302 .channelCount = 1, 00303 .sampleFormat = paInt16, 00304 .suggestedLatency = (1.0 / 50.0), /* 20 ms */ 00305 .device = paNoDevice, 00306 }; 00307 PaDeviceIndex idx, num_devices, def_input, def_output; 00308 00309 if (!(num_devices = Pa_GetDeviceCount())) 00310 return res; 00311 00312 def_input = Pa_GetDefaultInputDevice(); 00313 def_output = Pa_GetDefaultOutputDevice(); 00314 00315 for (idx = 0; 00316 idx < num_devices && (input_params.device == paNoDevice 00317 || output_params.device == paNoDevice); 00318 idx++) 00319 { 00320 const PaDeviceInfo *dev = Pa_GetDeviceInfo(idx); 00321 00322 if (dev->maxInputChannels) { 00323 if ( (idx == def_input && !strcasecmp(pvt->input_device, "default")) || 00324 !strcasecmp(pvt->input_device, dev->name) ) 00325 input_params.device = idx; 00326 } 00327 00328 if (dev->maxOutputChannels) { 00329 if ( (idx == def_output && !strcasecmp(pvt->output_device, "default")) || 00330 !strcasecmp(pvt->output_device, dev->name) ) 00331 output_params.device = idx; 00332 } 00333 } 00334 00335 if (input_params.device == paNoDevice) 00336 ast_log(LOG_ERROR, "No input device found for console device '%s'\n", pvt->name); 00337 if (output_params.device == paNoDevice) 00338 ast_log(LOG_ERROR, "No output device found for console device '%s'\n", pvt->name); 00339 00340 res = Pa_OpenStream(&pvt->stream, &input_params, &output_params, 00341 SAMPLE_RATE, NUM_SAMPLES, paNoFlag, NULL, NULL); 00342 } 00343 00344 return res; 00345 }
| static int pvt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1429 of file chan_console.c.
References CMP_MATCH, CMP_STOP, and console_pvt::name.
Referenced by load_module().
01430 { 01431 struct console_pvt *pvt = obj, *pvt2 = arg; 01432 01433 return !strcasecmp(pvt->name, pvt2->name) ? CMP_MATCH | CMP_STOP : 0; 01434 }
| static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1305 of file chan_console.c.
References ast_string_field_free_memory.
Referenced by build_device(), load_module(), and unload_module().
01306 { 01307 struct console_pvt *pvt = obj; 01308 01309 ast_string_field_free_memory(pvt); 01310 }
| static int pvt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1422 of file chan_console.c.
References ast_str_case_hash(), and console_pvt::name.
Referenced by load_module().
01423 { 01424 const struct console_pvt *pvt = obj; 01425 01426 return ast_str_case_hash(pvt->name); 01427 }
| static int pvt_mark_destroy_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1353 of file chan_console.c.
References console_pvt::destroy.
Referenced by load_config().
01354 { 01355 struct console_pvt *pvt = obj; 01356 pvt->destroy = 1; 01357 return 0; 01358 }
| static struct console_pvt* ref_pvt | ( | struct console_pvt * | pvt | ) | [static, read] |
Definition at line 228 of file chan_console.c.
References ao2_ref.
Referenced by console_new(), get_active_pvt(), and set_active().
00229 { 00230 if (pvt) 00231 ao2_ref(pvt, +1); 00232 return pvt; 00233 }
| static int reload | ( | void | ) | [static] |
Definition at line 1510 of file chan_console.c.
References load_config().
01511 { 01512 return load_config(1); 01513 }
| static void set_active | ( | struct console_pvt * | pvt, | |
| const char * | value | |||
| ) | [static] |
Definition at line 1128 of file chan_console.c.
References active_lock, ast_log(), ast_rwlock_unlock(), ast_rwlock_wrlock(), ast_true(), globals, LOG_ERROR, ref_pvt(), and unref_pvt().
Referenced by cli_console_active(), and store_config_core().
01129 { 01130 if (pvt == &globals) { 01131 ast_log(LOG_ERROR, "active is only valid as a per-device setting\n"); 01132 return; 01133 } 01134 01135 if (!ast_true(value)) 01136 return; 01137 01138 ast_rwlock_wrlock(&active_lock); 01139 if (active_pvt) 01140 unref_pvt(active_pvt); 01141 active_pvt = ref_pvt(pvt); 01142 ast_rwlock_unlock(&active_lock); 01143 }
| static void set_pvt_defaults | ( | struct console_pvt * | pvt | ) | [static] |
Set default values for a pvt struct.
Definition at line 1230 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().
01231 { 01232 if (pvt == &globals) { 01233 ast_string_field_set(pvt, mohinterpret, "default"); 01234 ast_string_field_set(pvt, context, "default"); 01235 ast_string_field_set(pvt, exten, "s"); 01236 ast_string_field_set(pvt, language, ""); 01237 ast_string_field_set(pvt, cid_num, ""); 01238 ast_string_field_set(pvt, cid_name, ""); 01239 ast_string_field_set(pvt, parkinglot, ""); 01240 01241 pvt->overridecontext = 0; 01242 pvt->autoanswer = 0; 01243 } else { 01244 ast_mutex_lock(&globals_lock); 01245 01246 ast_string_field_set(pvt, mohinterpret, globals.mohinterpret); 01247 ast_string_field_set(pvt, context, globals.context); 01248 ast_string_field_set(pvt, exten, globals.exten); 01249 ast_string_field_set(pvt, language, globals.language); 01250 ast_string_field_set(pvt, cid_num, globals.cid_num); 01251 ast_string_field_set(pvt, cid_name, globals.cid_name); 01252 ast_string_field_set(pvt, parkinglot, globals.parkinglot); 01253 01254 pvt->overridecontext = globals.overridecontext; 01255 pvt->autoanswer = globals.autoanswer; 01256 01257 ast_mutex_unlock(&globals_lock); 01258 } 01259 }
| static int start_stream | ( | struct console_pvt * | pvt | ) | [static] |
Definition at line 347 of file chan_console.c.
References ast_debug, ast_log(), ast_pthread_create_background, console_pvt_lock, console_pvt_unlock, LOG_ERROR, LOG_WARNING, open_stream(), console_pvt::stream, stream_monitor(), console_pvt::streamstate, and console_pvt::thread.
Referenced by console_answer(), console_call(), and console_new().
00348 { 00349 PaError res; 00350 int ret_val = 0; 00351 00352 console_pvt_lock(pvt); 00353 00354 if (pvt->streamstate) 00355 goto return_unlock; 00356 00357 pvt->streamstate = 1; 00358 ast_debug(1, "Starting stream\n"); 00359 00360 res = open_stream(pvt); 00361 if (res != paNoError) { 00362 ast_log(LOG_WARNING, "Failed to open stream - (%d) %s\n", 00363 res, Pa_GetErrorText(res)); 00364 ret_val = -1; 00365 goto return_unlock; 00366 } 00367 00368 res = Pa_StartStream(pvt->stream); 00369 if (res != paNoError) { 00370 ast_log(LOG_WARNING, "Failed to start stream - (%d) %s\n", 00371 res, Pa_GetErrorText(res)); 00372 ret_val = -1; 00373 goto return_unlock; 00374 } 00375 00376 if (ast_pthread_create_background(&pvt->thread, NULL, stream_monitor, pvt)) { 00377 ast_log(LOG_ERROR, "Failed to start stream monitor thread\n"); 00378 ret_val = -1; 00379 } 00380 00381 return_unlock: 00382 console_pvt_unlock(pvt); 00383 00384 return ret_val; 00385 }
| static int stop_stream | ( | struct console_pvt * | pvt | ) | [static] |
Definition at line 387 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().
00388 { 00389 if (!pvt->streamstate || pvt->thread == AST_PTHREADT_NULL) 00390 return 0; 00391 00392 pthread_cancel(pvt->thread); 00393 pthread_kill(pvt->thread, SIGURG); 00394 pthread_join(pvt->thread, NULL); 00395 00396 console_pvt_lock(pvt); 00397 Pa_AbortStream(pvt->stream); 00398 Pa_CloseStream(pvt->stream); 00399 pvt->stream = NULL; 00400 pvt->streamstate = 0; 00401 console_pvt_unlock(pvt); 00402 00403 return 0; 00404 }
| static void stop_streams | ( | void | ) | [static] |
Definition at line 1436 of file chan_console.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, console_pvt::hookstate, stop_stream(), and unref_pvt().
Referenced by unload_module().
01437 { 01438 struct console_pvt *pvt; 01439 struct ao2_iterator i; 01440 01441 i = ao2_iterator_init(pvts, 0); 01442 while ((pvt = ao2_iterator_next(&i))) { 01443 if (pvt->hookstate) 01444 stop_stream(pvt); 01445 unref_pvt(pvt); 01446 } 01447 ao2_iterator_destroy(&i); 01448 }
| static void store_callerid | ( | struct console_pvt * | pvt, | |
| const char * | value | |||
| ) | [static] |
Definition at line 1261 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().
01262 { 01263 char cid_name[256]; 01264 char cid_num[256]; 01265 01266 ast_callerid_split(value, cid_name, sizeof(cid_name), 01267 cid_num, sizeof(cid_num)); 01268 01269 ast_string_field_set(pvt, cid_name, cid_name); 01270 ast_string_field_set(pvt, cid_num, cid_num); 01271 }
| 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 1278 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(), and load_config().
01279 { 01280 if (pvt == &globals && !ast_jb_read_conf(&global_jbconf, var, value)) 01281 return; 01282 01283 CV_START(var, value); 01284 01285 CV_STRFIELD("context", pvt, context); 01286 CV_STRFIELD("extension", pvt, exten); 01287 CV_STRFIELD("mohinterpret", pvt, mohinterpret); 01288 CV_STRFIELD("language", pvt, language); 01289 CV_F("callerid", store_callerid(pvt, value)); 01290 CV_BOOL("overridecontext", pvt->overridecontext); 01291 CV_BOOL("autoanswer", pvt->autoanswer); 01292 CV_STRFIELD("parkinglot", pvt, parkinglot); 01293 01294 if (pvt != &globals) { 01295 CV_F("active", set_active(pvt, value)) 01296 CV_STRFIELD("input_device", pvt, input_device); 01297 CV_STRFIELD("output_device", pvt, output_device); 01298 } 01299 01300 ast_log(LOG_WARNING, "Unknown option '%s'\n", var); 01301 01302 CV_END; 01303 }
| static void* stream_monitor | ( | void * | data | ) | [static] |
Stream monitor thread.
This function runs in its own thread to monitor data coming in from a portaudio stream. When enough data is available, it is queued up to be read from the Asterisk channel.
Definition at line 260 of file chan_console.c.
References AST_FORMAT_SLINEAR16, AST_FRAME_VOICE, ast_queue_frame(), buf, ast_frame::frametype, NUM_SAMPLES, console_pvt::owner, ast_frame::samples, and console_pvt::stream.
Referenced by start_stream().
00261 { 00262 struct console_pvt *pvt = data; 00263 char buf[NUM_SAMPLES * sizeof(int16_t)]; 00264 PaError res; 00265 struct ast_frame f = { 00266 .frametype = AST_FRAME_VOICE, 00267 .subclass = AST_FORMAT_SLINEAR16, 00268 .src = "console_stream_monitor", 00269 .data.ptr = buf, 00270 .datalen = sizeof(buf), 00271 .samples = sizeof(buf) / sizeof(int16_t), 00272 }; 00273 00274 for (;;) { 00275 pthread_testcancel(); 00276 res = Pa_ReadStream(pvt->stream, buf, sizeof(buf) / sizeof(int16_t)); 00277 pthread_testcancel(); 00278 00279 if (res == paNoError) 00280 ast_queue_frame(pvt->owner, &f); 00281 } 00282 00283 return NULL; 00284 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 1450 of file chan_console.c.
References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), globals, pvt_destructor(), and stop_streams().
01451 { 01452 ast_channel_unregister(&console_tech); 01453 ast_cli_unregister_multiple(cli_console, ARRAY_LEN(cli_console)); 01454 01455 stop_streams(); 01456 01457 Pa_Terminate(); 01458 01459 /* Will unref all the pvts so they will get destroyed, too */ 01460 ao2_ref(pvts, -1); 01461 01462 pvt_destructor(&globals); 01463 01464 return 0; 01465 }
| static struct console_pvt* unref_pvt | ( | struct console_pvt * | pvt | ) | [static, read] |
Definition at line 235 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().
00236 { 00237 ao2_ref(pvt, -1); 00238 return NULL; 00239 }
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 1519 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.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1519 of file chan_console.c.
struct ast_cli_entry cli_console[] [static] |
Definition at line 1212 of file chan_console.c.
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 205 of file chan_console.c.
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 182 of file chan_console.c.
Referenced by console_new(), load_config(), and store_config_core().
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 load_config(), load_module(), set_active(), set_pvt_defaults(), store_config_core(), and unload_module().
ast_mutex_t globals_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 163 of file chan_console.c.
Referenced by load_config(), and set_pvt_defaults().
struct ao2_container* pvts [static] |
Definition at line 165 of file chan_console.c.
Referenced by handle_ss7_block_cic(), handle_ss7_block_linkset(), handle_ss7_unblock_cic(), handle_ss7_unblock_linkset(), pri_create_trunkgroup(), and setup_dahdi().
1.6.1