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