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. | |
| #define | V_BEGIN " --- <(\"<) --- " |
| Dance, Kirby, Dance! | |
| #define | V_END " --- (>\")> ---\n" |
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) |
| 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) |
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 = "0901e4e500243c855563a2d78b0c03e4" , .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 |
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.
Referenced by ast_tone_detect_init(), goertzel_init(), and open_stream().
| #define SUPPORTED_FORMATS ( AST_FORMAT_SLINEAR16 ) |
Formats natively supported by this module.
Definition at line 204 of file chan_console.c.
Referenced by console_request().
| #define TEXT_SIZE 256 |
Maximum text message length.
Definition at line 102 of file chan_console.c.
Referenced by cli_console_sendtext(), and console_sendtext().
| #define V_BEGIN " --- <(\"<) --- " |
Dance, Kirby, Dance!
Definition at line 105 of file chan_console.c.
Referenced by cli_console_mute(), console_answer(), console_call(), console_digit_begin(), console_digit_end(), console_hangup(), console_indicate(), and console_text().
| #define V_END " --- (>\")> ---\n" |
Definition at line 106 of file chan_console.c.
Referenced by cli_console_mute(), console_answer(), console_call(), console_digit_begin(), console_digit_end(), console_hangup(), console_indicate(), and console_text().
| static void __reg_module | ( | void | ) | [static] |
Definition at line 1522 of file chan_console.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 1522 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 1323 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().
01324 { 01325 struct ast_variable *v; 01326 struct console_pvt *pvt; 01327 int new = 0; 01328 01329 if ((pvt = find_pvt(name))) { 01330 console_pvt_lock(pvt); 01331 set_pvt_defaults(pvt); 01332 pvt->destroy = 0; 01333 } else { 01334 if (!(pvt = ao2_alloc(sizeof(*pvt), pvt_destructor))) 01335 return; 01336 init_pvt(pvt, name); 01337 set_pvt_defaults(pvt); 01338 new = 1; 01339 } 01340 01341 for (v = ast_variable_browse(cfg, name); v; v = v->next) 01342 store_config_core(pvt, v->name, v->value); 01343 01344 if (new) 01345 ao2_link(pvts, pvt); 01346 else 01347 console_pvt_unlock(pvt); 01348 01349 unref_pvt(pvt); 01350 }
| 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 {set|show} active [<device>]"; 01153 e->usage = 01154 "Usage: console {set|show} active [<device>]\n" 01155 " Set or show the active console device for the Asterisk CLI.\n"; 01156 return NULL; 01157 case CLI_GENERATE: 01158 if (a->pos == e->args) { 01159 struct ao2_iterator i; 01160 int x = 0; 01161 char *res = NULL; 01162 i = ao2_iterator_init(pvts, 0); 01163 while ((pvt = ao2_iterator_next(&i))) { 01164 if (++x > a->n && !strncasecmp(pvt->name, a->word, strlen(a->word))) 01165 res = ast_strdup(pvt->name); 01166 unref_pvt(pvt); 01167 if (res) { 01168 ao2_iterator_destroy(&i); 01169 return res; 01170 } 01171 } 01172 ao2_iterator_destroy(&i); 01173 } 01174 return NULL; 01175 } 01176 01177 if (a->argc < e->args) 01178 return CLI_SHOWUSAGE; 01179 01180 if (a->argc == 3) { 01181 pvt = get_active_pvt(); 01182 01183 if (!pvt) 01184 ast_cli(a->fd, "No device is currently set as the active console device.\n"); 01185 else { 01186 console_pvt_lock(pvt); 01187 ast_cli(a->fd, "The active console device is '%s'.\n", pvt->name); 01188 console_pvt_unlock(pvt); 01189 pvt = unref_pvt(pvt); 01190 } 01191 01192 return CLI_SUCCESS; 01193 } 01194 01195 if (!(pvt = find_pvt(a->argv[e->args]))) { 01196 ast_cli(a->fd, "Could not find a device called '%s'.\n", a->argv[e->args]); 01197 return CLI_FAILURE; 01198 } 01199 01200 set_active(pvt, "yes"); 01201 01202 console_pvt_lock(pvt); 01203 ast_cli(a->fd, "The active console device has been set to '%s'\n", pvt->name); 01204 console_pvt_unlock(pvt); 01205 01206 unref_pvt(pvt); 01207 01208 return CLI_SUCCESS; 01209 }
| 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|show} autoanswer [on|off]"; 00692 e->usage = 00693 "Usage: console {set|show} 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::name, 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 1359 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().
01360 { 01361 struct ao2_iterator i; 01362 struct console_pvt *pvt; 01363 01364 i = ao2_iterator_init(pvts, 0); 01365 while ((pvt = ao2_iterator_next(&i))) { 01366 if (pvt->destroy) { 01367 ao2_unlink(pvts, pvt); 01368 ast_rwlock_wrlock(&active_lock); 01369 if (active_pvt == pvt) 01370 active_pvt = unref_pvt(pvt); 01371 ast_rwlock_unlock(&active_lock); 01372 } 01373 unref_pvt(pvt); 01374 } 01375 ao2_iterator_destroy(&i); 01376 }
| 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 1311 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().
01312 { 01313 pvt->thread = AST_PTHREADT_NULL; 01314 01315 if (ast_string_field_init(pvt, 32)) 01316 return -1; 01317 01318 ast_string_field_set(pvt, name, S_OR(name, "")); 01319 01320 return 0; 01321 }
| 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 1384 of file chan_console.c.
References ao2_callback, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_variable_browse(), build_device(), CONFIG_STATUS_FILEINVALID, context, 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().
01385 { 01386 struct ast_config *cfg; 01387 struct ast_variable *v; 01388 struct ast_flags config_flags = { 0 }; 01389 char *context = NULL; 01390 01391 /* default values */ 01392 memcpy(&global_jbconf, &default_jbconf, sizeof(global_jbconf)); 01393 ast_mutex_lock(&globals_lock); 01394 set_pvt_defaults(&globals); 01395 ast_mutex_unlock(&globals_lock); 01396 01397 if (!(cfg = ast_config_load(config_file, config_flags))) { 01398 ast_log(LOG_NOTICE, "Unable to open configuration file %s!\n", config_file); 01399 return -1; 01400 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 01401 ast_log(LOG_NOTICE, "Config file %s has an invalid format\n", config_file); 01402 return -1; 01403 } 01404 01405 ao2_callback(pvts, OBJ_NODATA, pvt_mark_destroy_cb, NULL); 01406 01407 ast_mutex_lock(&globals_lock); 01408 for (v = ast_variable_browse(cfg, "general"); v; v = v->next) 01409 store_config_core(&globals, v->name, v->value); 01410 ast_mutex_unlock(&globals_lock); 01411 01412 while ((context = ast_category_browse(cfg, context))) { 01413 if (strcasecmp(context, "general")) 01414 build_device(cfg, context); 01415 } 01416 01417 ast_config_destroy(cfg); 01418 01419 destroy_pvts(); 01420 01421 return 0; 01422 }
| static int load_module | ( | void | ) | [static] |
Definition at line 1469 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().
01470 { 01471 PaError res; 01472 01473 init_pvt(&globals, NULL); 01474 01475 if (!(pvts = ao2_container_alloc(NUM_PVT_BUCKETS, pvt_hash_cb, pvt_cmp_cb))) 01476 goto return_error; 01477 01478 if (load_config(0)) 01479 goto return_error; 01480 01481 res = Pa_Initialize(); 01482 if (res != paNoError) { 01483 ast_log(LOG_WARNING, "Failed to initialize audio system - (%d) %s\n", 01484 res, Pa_GetErrorText(res)); 01485 goto return_error_pa_init; 01486 } 01487 01488 if (ast_channel_register(&console_tech)) { 01489 ast_log(LOG_ERROR, "Unable to register channel type 'Console'\n"); 01490 goto return_error_chan_reg; 01491 } 01492 01493 if (ast_cli_register_multiple(cli_console, ARRAY_LEN(cli_console))) 01494 goto return_error_cli_reg; 01495 01496 return AST_MODULE_LOAD_SUCCESS; 01497 01498 return_error_cli_reg: 01499 ast_cli_unregister_multiple(cli_console, ARRAY_LEN(cli_console)); 01500 return_error_chan_reg: 01501 ast_channel_unregister(&console_tech); 01502 return_error_pa_init: 01503 Pa_Terminate(); 01504 return_error: 01505 if (pvts) 01506 ao2_ref(pvts, -1); 01507 pvts = NULL; 01508 pvt_destructor(&globals); 01509 01510 return AST_MODULE_LOAD_DECLINE; 01511 }
| 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 1431 of file chan_console.c.
References CMP_MATCH, CMP_STOP, and console_pvt::name.
Referenced by load_module().
01432 { 01433 struct console_pvt *pvt = obj, *pvt2 = arg; 01434 01435 return !strcasecmp(pvt->name, pvt2->name) ? CMP_MATCH | CMP_STOP : 0; 01436 }
| static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1304 of file chan_console.c.
References ast_string_field_free_memory.
Referenced by build_device(), load_module(), and unload_module().
01305 { 01306 struct console_pvt *pvt = obj; 01307 01308 ast_string_field_free_memory(pvt); 01309 }
| static int pvt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1424 of file chan_console.c.
References ast_str_case_hash(), and console_pvt::name.
Referenced by load_module().
01425 { 01426 const struct console_pvt *pvt = obj; 01427 01428 return ast_str_case_hash(pvt->name); 01429 }
| static int pvt_mark_destroy_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1352 of file chan_console.c.
References console_pvt::destroy.
Referenced by load_config().
01353 { 01354 struct console_pvt *pvt = obj; 01355 pvt->destroy = 1; 01356 return 0; 01357 }
| 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 1513 of file chan_console.c.
References load_config().
01514 { 01515 return load_config(1); 01516 }
| 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 1229 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().
01230 { 01231 if (pvt == &globals) { 01232 ast_string_field_set(pvt, mohinterpret, "default"); 01233 ast_string_field_set(pvt, context, "default"); 01234 ast_string_field_set(pvt, exten, "s"); 01235 ast_string_field_set(pvt, language, ""); 01236 ast_string_field_set(pvt, cid_num, ""); 01237 ast_string_field_set(pvt, cid_name, ""); 01238 ast_string_field_set(pvt, parkinglot, ""); 01239 01240 pvt->overridecontext = 0; 01241 pvt->autoanswer = 0; 01242 } else { 01243 ast_mutex_lock(&globals_lock); 01244 01245 ast_string_field_set(pvt, mohinterpret, globals.mohinterpret); 01246 ast_string_field_set(pvt, context, globals.context); 01247 ast_string_field_set(pvt, exten, globals.exten); 01248 ast_string_field_set(pvt, language, globals.language); 01249 ast_string_field_set(pvt, cid_num, globals.cid_num); 01250 ast_string_field_set(pvt, cid_name, globals.cid_name); 01251 ast_string_field_set(pvt, parkinglot, globals.parkinglot); 01252 01253 pvt->overridecontext = globals.overridecontext; 01254 pvt->autoanswer = globals.autoanswer; 01255 01256 ast_mutex_unlock(&globals_lock); 01257 } 01258 }
| 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 1438 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().
01439 { 01440 struct console_pvt *pvt; 01441 struct ao2_iterator i; 01442 01443 i = ao2_iterator_init(pvts, 0); 01444 while ((pvt = ao2_iterator_next(&i))) { 01445 if (pvt->hookstate) 01446 stop_stream(pvt); 01447 unref_pvt(pvt); 01448 } 01449 ao2_iterator_destroy(&i); 01450 }
| static void store_callerid | ( | struct console_pvt * | pvt, | |
| const char * | value | |||
| ) | [static] |
Definition at line 1260 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().
01261 { 01262 char cid_name[256]; 01263 char cid_num[256]; 01264 01265 ast_callerid_split(value, cid_name, sizeof(cid_name), 01266 cid_num, sizeof(cid_num)); 01267 01268 ast_string_field_set(pvt, cid_name, cid_name); 01269 ast_string_field_set(pvt, cid_num, cid_num); 01270 }
| 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 1277 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().
01278 { 01279 if (pvt == &globals && !ast_jb_read_conf(&global_jbconf, var, value)) 01280 return; 01281 01282 CV_START(var, value); 01283 01284 CV_STRFIELD("context", pvt, context); 01285 CV_STRFIELD("extension", pvt, exten); 01286 CV_STRFIELD("mohinterpret", pvt, mohinterpret); 01287 CV_STRFIELD("language", pvt, language); 01288 CV_F("callerid", store_callerid(pvt, value)); 01289 CV_BOOL("overridecontext", pvt->overridecontext); 01290 CV_BOOL("autoanswer", pvt->autoanswer); 01291 CV_STRFIELD("parkinglot", pvt, parkinglot); 01292 01293 if (pvt != &globals) { 01294 CV_F("active", set_active(pvt, value)) 01295 CV_STRFIELD("input_device", pvt, input_device); 01296 CV_STRFIELD("output_device", pvt, output_device); 01297 } 01298 01299 ast_log(LOG_WARNING, "Unknown option '%s'\n", var); 01300 01301 CV_END; 01302 }
| 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 1452 of file chan_console.c.
References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), globals, pvt_destructor(), and stop_streams().
01453 { 01454 ast_channel_unregister(&console_tech); 01455 ast_cli_unregister_multiple(cli_console, ARRAY_LEN(cli_console)); 01456 01457 stop_streams(); 01458 01459 Pa_Terminate(); 01460 01461 /* Will unref all the pvts so they will get destroyed, too */ 01462 ao2_ref(pvts, -1); 01463 01464 pvt_destructor(&globals); 01465 01466 return 0; 01467 }
| 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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 1522 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 1522 of file chan_console.c.
struct ast_cli_entry cli_console[] [static] |
Definition at line 1211 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.2