#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 | MAX(a, b) ((a) > (b) ? (a) : (b)) |
| #define | MIN(a, b) ((a) < (b) ? (a) : (b)) |
| #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 void | fini_active_lock (void) |
| static struct console_pvt * | get_active_pvt (void) |
| static void | init_active_lock (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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } |
| static ast_rwlock_t | active_lock |
| static struct console_pvt * | active_pvt |
| static const 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_MUTEX_INITIALIZER ) |
| static struct ao2_container * | pvts |
Definition in file chan_console.c.
| #define console_pvt_lock | ( | pvt | ) | ao2_lock(pvt) |
lock a console_pvt struct
Definition at line 228 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 231 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 MAX | ( | a, | |||
| b | ) | ((a) > (b) ? (a) : (b)) |
Definition at line 108 of file chan_console.c.
Referenced by __ast_answer(), and handle_response_register().
| #define MIN | ( | a, | |||
| b | ) | ((a) < (b) ? (a) : (b)) |
Definition at line 105 of file chan_console.c.
| #define NUM_PVT_BUCKETS 7 |
| #define NUM_SAMPLES 320 |
The number of samples to configure the portaudio stream for.
320 samples (20 ms) is the most common frame size in Asterisk. So, the code in this module reads 320 sample frames from the portaudio stream and queues them up on the Asterisk channel. Frames of any size can be written to a portaudio stream, but the portaudio documentation does say that for high performance applications, the data should be written to Pa_WriteStream in the same size as what is used to initialize the stream.
Definition at line 89 of file chan_console.c.
Referenced by open_stream(), and stream_monitor().
| #define OUTPUT_CHANNELS 1 |
| #define SAMPLE_RATE 16000 |
The sample rate to request from PortAudio.
Definition at line 77 of file chan_console.c.
| #define SUPPORTED_FORMATS ( AST_FORMAT_SLINEAR16 ) |
Formats natively supported by this module.
Definition at line 208 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 112 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 113 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 1520 of file chan_console.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 1520 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 653 of file chan_console.c.
References ast_strdup, and console_pvt::overridecontext.
Referenced by cli_console_dial(), console_dial(), and console_transfer().
00654 { 00655 if (ext == NULL || ctx == NULL) 00656 return NULL; /* error */ 00657 00658 *ext = *ctx = NULL; 00659 00660 if (src && *src != '\0') 00661 *ext = ast_strdup(src); 00662 00663 if (*ext == NULL) 00664 return NULL; 00665 00666 if (!pvt->overridecontext) { 00667 /* parse from the right */ 00668 *ctx = strrchr(*ext, '@'); 00669 if (*ctx) 00670 *(*ctx)++ = '\0'; 00671 } 00672 00673 return *ext; 00674 }
| 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(), and reload_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 1149 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.
01150 { 01151 struct console_pvt *pvt; 01152 01153 switch (cmd) { 01154 case CLI_INIT: 01155 e->command = "console active"; 01156 e->usage = 01157 "Usage: console active [device]\n" 01158 " If no device is specified. The active console device will be shown.\n" 01159 "Otherwise, the specified device will become the console device active for\n" 01160 "the Asterisk CLI.\n"; 01161 return NULL; 01162 case CLI_GENERATE: 01163 if (a->pos == e->args) { 01164 struct ao2_iterator i; 01165 int x = 0; 01166 char *res = NULL; 01167 i = ao2_iterator_init(pvts, 0); 01168 while ((pvt = ao2_iterator_next(&i))) { 01169 if (++x > a->n && !strncasecmp(pvt->name, a->word, strlen(a->word))) 01170 res = ast_strdup(pvt->name); 01171 unref_pvt(pvt); 01172 if (res) { 01173 ao2_iterator_destroy(&i); 01174 return res; 01175 } 01176 } 01177 ao2_iterator_destroy(&i); 01178 } 01179 return NULL; 01180 } 01181 01182 if (a->argc < e->args) 01183 return CLI_SHOWUSAGE; 01184 01185 if (a->argc == e->args) { 01186 pvt = get_active_pvt(); 01187 01188 if (!pvt) 01189 ast_cli(a->fd, "No device is currently set as the active console device.\n"); 01190 else { 01191 console_pvt_lock(pvt); 01192 ast_cli(a->fd, "The active console device is '%s'.\n", pvt->name); 01193 console_pvt_unlock(pvt); 01194 pvt = unref_pvt(pvt); 01195 } 01196 01197 return CLI_SUCCESS; 01198 } 01199 01200 if (!(pvt = find_pvt(a->argv[e->args]))) { 01201 ast_cli(a->fd, "Could not find a device called '%s'.\n", a->argv[e->args]); 01202 return CLI_FAILURE; 01203 } 01204 01205 set_active(pvt, "yes"); 01206 01207 console_pvt_lock(pvt); 01208 ast_cli(a->fd, "The active console device has been set to '%s'\n", pvt->name); 01209 console_pvt_unlock(pvt); 01210 01211 unref_pvt(pvt); 01212 01213 return CLI_SUCCESS; 01214 }
| 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 1029 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.
01030 { 01031 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; 01032 struct console_pvt *pvt = get_active_pvt(); 01033 01034 switch (cmd) { 01035 case CLI_INIT: 01036 e->command = "console answer"; 01037 e->usage = 01038 "Usage: console answer\n" 01039 " Answers an incoming call on the console channel.\n"; 01040 return NULL; 01041 01042 case CLI_GENERATE: 01043 return NULL; /* no completion */ 01044 } 01045 01046 if (!pvt) { 01047 ast_cli(a->fd, "No console device is set as active\n"); 01048 return CLI_FAILURE; 01049 } 01050 01051 if (a->argc != e->args) { 01052 unref_pvt(pvt); 01053 return CLI_SHOWUSAGE; 01054 } 01055 01056 if (!pvt->owner) { 01057 ast_cli(a->fd, "No one is calling us\n"); 01058 unref_pvt(pvt); 01059 return CLI_FAILURE; 01060 } 01061 01062 pvt->hookstate = 1; 01063 01064 ast_indicate(pvt->owner, -1); 01065 01066 ast_queue_frame(pvt->owner, &f); 01067 01068 unref_pvt(pvt); 01069 01070 return CLI_SUCCESS; 01071 }
| static char* cli_console_autoanswer | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 687 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.
00689 { 00690 struct console_pvt *pvt = get_active_pvt(); 00691 char *res = CLI_SUCCESS; 00692 00693 switch (cmd) { 00694 case CLI_INIT: 00695 e->command = "console set autoanswer [on|off]"; 00696 e->usage = 00697 "Usage: console set autoanswer [on|off]\n" 00698 " Enables or disables autoanswer feature. If used without\n" 00699 " argument, displays the current on/off status of autoanswer.\n" 00700 " The default value of autoanswer is in 'oss.conf'.\n"; 00701 return NULL; 00702 00703 case CLI_GENERATE: 00704 return NULL; 00705 } 00706 00707 if (!pvt) { 00708 ast_cli(a->fd, "No console device is set as active.\n"); 00709 return CLI_FAILURE; 00710 } 00711 00712 if (a->argc == e->args - 1) { 00713 ast_cli(a->fd, "Auto answer is %s.\n", pvt->autoanswer ? "on" : "off"); 00714 unref_pvt(pvt); 00715 return CLI_SUCCESS; 00716 } 00717 00718 if (a->argc != e->args) { 00719 unref_pvt(pvt); 00720 return CLI_SHOWUSAGE; 00721 } 00722 00723 if (!strcasecmp(a->argv[e->args-1], "on")) 00724 pvt->autoanswer = 1; 00725 else if (!strcasecmp(a->argv[e->args - 1], "off")) 00726 pvt->autoanswer = 0; 00727 else 00728 res = CLI_SHOWUSAGE; 00729 00730 unref_pvt(pvt); 00731 00732 return CLI_SUCCESS; 00733 }
| static char* cli_console_dial | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 772 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.
00773 { 00774 char *s = NULL; 00775 const char *mye = NULL, *myc = NULL; 00776 struct console_pvt *pvt = get_active_pvt(); 00777 00778 if (cmd == CLI_INIT) { 00779 e->command = "console dial"; 00780 e->usage = 00781 "Usage: console dial [extension[@context]]\n" 00782 " Dials a given extension (and context if specified)\n"; 00783 return NULL; 00784 } else if (cmd == CLI_GENERATE) 00785 return NULL; 00786 00787 if (!pvt) { 00788 ast_cli(a->fd, "No console device is currently set as active\n"); 00789 return CLI_FAILURE; 00790 } 00791 00792 if (a->argc > e->args + 1) 00793 return CLI_SHOWUSAGE; 00794 00795 if (pvt->owner) { /* already in a call */ 00796 int i; 00797 struct ast_frame f = { AST_FRAME_DTMF, 0 }; 00798 00799 if (a->argc == e->args) { /* argument is mandatory here */ 00800 ast_cli(a->fd, "Already in a call. You can only dial digits until you hangup.\n"); 00801 unref_pvt(pvt); 00802 return CLI_FAILURE; 00803 } 00804 s = a->argv[e->args]; 00805 /* send the string one char at a time */ 00806 for (i = 0; i < strlen(s); i++) { 00807 f.subclass = s[i]; 00808 ast_queue_frame(pvt->owner, &f); 00809 } 00810 unref_pvt(pvt); 00811 return CLI_SUCCESS; 00812 } 00813 00814 /* if we have an argument split it into extension and context */ 00815 if (a->argc == e->args + 1) { 00816 char *ext = NULL, *con = NULL; 00817 s = ast_ext_ctx(pvt, a->argv[e->args], &ext, &con); 00818 ast_debug(1, "provided '%s', exten '%s' context '%s'\n", 00819 a->argv[e->args], mye, myc); 00820 mye = ext; 00821 myc = con; 00822 } 00823 00824 /* supply default values if needed */ 00825 if (ast_strlen_zero(mye)) 00826 mye = pvt->exten; 00827 if (ast_strlen_zero(myc)) 00828 myc = pvt->context; 00829 00830 if (ast_exists_extension(NULL, myc, mye, 1, NULL)) { 00831 console_pvt_lock(pvt); 00832 pvt->hookstate = 1; 00833 console_new(pvt, mye, myc, AST_STATE_RINGING); 00834 console_pvt_unlock(pvt); 00835 } else 00836 ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc); 00837 00838 if (s) 00839 free(s); 00840 00841 unref_pvt(pvt); 00842 00843 return CLI_SUCCESS; 00844 }
| static char* cli_console_flash | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 735 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.
00736 { 00737 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH }; 00738 struct console_pvt *pvt = get_active_pvt(); 00739 00740 if (cmd == CLI_INIT) { 00741 e->command = "console flash"; 00742 e->usage = 00743 "Usage: console flash\n" 00744 " Flashes the call currently placed on the console.\n"; 00745 return NULL; 00746 } else if (cmd == CLI_GENERATE) 00747 return NULL; 00748 00749 if (!pvt) { 00750 ast_cli(a->fd, "No console device is set as active\n"); 00751 return CLI_FAILURE; 00752 } 00753 00754 if (a->argc != e->args) 00755 return CLI_SHOWUSAGE; 00756 00757 if (!pvt->owner) { 00758 ast_cli(a->fd, "No call to flash\n"); 00759 unref_pvt(pvt); 00760 return CLI_FAILURE; 00761 } 00762 00763 pvt->hookstate = 0; 00764 00765 ast_queue_frame(pvt->owner, &f); 00766 00767 unref_pvt(pvt); 00768 00769 return CLI_SUCCESS; 00770 }
| static char* cli_console_hangup | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 846 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.
00847 { 00848 struct console_pvt *pvt = get_active_pvt(); 00849 00850 if (cmd == CLI_INIT) { 00851 e->command = "console hangup"; 00852 e->usage = 00853 "Usage: console hangup\n" 00854 " Hangs up any call currently placed on the console.\n"; 00855 return NULL; 00856 } else if (cmd == CLI_GENERATE) 00857 return NULL; 00858 00859 if (!pvt) { 00860 ast_cli(a->fd, "No console device is set as active\n"); 00861 return CLI_FAILURE; 00862 } 00863 00864 if (a->argc != e->args) 00865 return CLI_SHOWUSAGE; 00866 00867 if (!pvt->owner && !pvt->hookstate) { 00868 ast_cli(a->fd, "No call to hang up\n"); 00869 unref_pvt(pvt); 00870 return CLI_FAILURE; 00871 } 00872 00873 pvt->hookstate = 0; 00874 if (pvt->owner) 00875 ast_queue_hangup(pvt->owner); 00876 00877 unref_pvt(pvt); 00878 00879 return CLI_SUCCESS; 00880 }
| static char* cli_console_mute | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 882 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.
00883 { 00884 char *s; 00885 struct console_pvt *pvt = get_active_pvt(); 00886 char *res = CLI_SUCCESS; 00887 00888 if (cmd == CLI_INIT) { 00889 e->command = "console {mute|unmute}"; 00890 e->usage = 00891 "Usage: console {mute|unmute}\n" 00892 " Mute/unmute the microphone.\n"; 00893 return NULL; 00894 } else if (cmd == CLI_GENERATE) 00895 return NULL; 00896 00897 if (!pvt) { 00898 ast_cli(a->fd, "No console device is set as active\n"); 00899 return CLI_FAILURE; 00900 } 00901 00902 if (a->argc != e->args) 00903 return CLI_SHOWUSAGE; 00904 00905 s = a->argv[e->args-1]; 00906 if (!strcasecmp(s, "mute")) 00907 pvt->muted = 1; 00908 else if (!strcasecmp(s, "unmute")) 00909 pvt->muted = 0; 00910 else 00911 res = CLI_SHOWUSAGE; 00912 00913 ast_verb(1, V_BEGIN "The Console is now %s" V_END, 00914 pvt->muted ? "Muted" : "Unmuted"); 00915 00916 unref_pvt(pvt); 00917 00918 return res; 00919 }
| 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 1079 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.
01080 { 01081 char buf[TEXT_SIZE]; 01082 struct console_pvt *pvt = get_active_pvt(); 01083 struct ast_frame f = { 01084 .frametype = AST_FRAME_TEXT, 01085 .data = buf, 01086 .src = "console_send_text", 01087 }; 01088 int len; 01089 01090 if (cmd == CLI_INIT) { 01091 e->command = "console send text"; 01092 e->usage = 01093 "Usage: console send text <message>\n" 01094 " Sends a text message for display on the remote terminal.\n"; 01095 return NULL; 01096 } else if (cmd == CLI_GENERATE) 01097 return NULL; 01098 01099 if (!pvt) { 01100 ast_cli(a->fd, "No console device is set as active\n"); 01101 return CLI_FAILURE; 01102 } 01103 01104 if (a->argc < e->args + 1) { 01105 unref_pvt(pvt); 01106 return CLI_SHOWUSAGE; 01107 } 01108 01109 if (!pvt->owner) { 01110 ast_cli(a->fd, "Not in a call\n"); 01111 unref_pvt(pvt); 01112 return CLI_FAILURE; 01113 } 01114 01115 ast_join(buf, sizeof(buf) - 1, a->argv + e->args); 01116 if (ast_strlen_zero(buf)) { 01117 unref_pvt(pvt); 01118 return CLI_SHOWUSAGE; 01119 } 01120 01121 len = strlen(buf); 01122 buf[len] = '\n'; 01123 f.datalen = len + 1; 01124 01125 ast_queue_frame(pvt->owner, &f); 01126 01127 unref_pvt(pvt); 01128 01129 return CLI_SUCCESS; 01130 }
| static char* cli_list_available | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 921 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.
00922 { 00923 PaDeviceIndex index, num, def_input, def_output; 00924 00925 if (cmd == CLI_INIT) { 00926 e->command = "console list available"; 00927 e->usage = 00928 "Usage: console list available\n" 00929 " List all available devices.\n"; 00930 return NULL; 00931 } else if (cmd == CLI_GENERATE) 00932 return NULL; 00933 00934 if (a->argc != e->args) 00935 return CLI_SHOWUSAGE; 00936 00937 ast_cli(a->fd, "\n" 00938 "=============================================================\n" 00939 "=== Available Devices =======================================\n" 00940 "=============================================================\n" 00941 "===\n"); 00942 00943 num = Pa_GetDeviceCount(); 00944 if (!num) { 00945 ast_cli(a->fd, "(None)\n"); 00946 return CLI_SUCCESS; 00947 } 00948 00949 def_input = Pa_GetDefaultInputDevice(); 00950 def_output = Pa_GetDefaultOutputDevice(); 00951 for (index = 0; index < num; index++) { 00952 const PaDeviceInfo *dev = Pa_GetDeviceInfo(index); 00953 if (!dev) 00954 continue; 00955 ast_cli(a->fd, "=== ---------------------------------------------------------\n" 00956 "=== Device Name: %s\n", dev->name); 00957 if (dev->maxInputChannels) 00958 ast_cli(a->fd, "=== ---> %sInput Device\n", (index == def_input) ? "Default " : ""); 00959 if (dev->maxOutputChannels) 00960 ast_cli(a->fd, "=== ---> %sOutput Device\n", (index == def_output) ? "Default " : ""); 00961 ast_cli(a->fd, "=== ---------------------------------------------------------\n===\n"); 00962 } 00963 00964 ast_cli(a->fd, "=============================================================\n\n"); 00965 00966 return CLI_SUCCESS; 00967 }
| static char* cli_list_devices | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 969 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, unref_pvt(), and ast_cli_entry::usage.
00970 { 00971 struct ao2_iterator i; 00972 struct console_pvt *pvt; 00973 00974 if (cmd == CLI_INIT) { 00975 e->command = "console list devices"; 00976 e->usage = 00977 "Usage: console list devices\n" 00978 " List all configured devices.\n"; 00979 return NULL; 00980 } else if (cmd == CLI_GENERATE) 00981 return NULL; 00982 00983 if (a->argc != e->args) 00984 return CLI_SHOWUSAGE; 00985 00986 ast_cli(a->fd, "\n" 00987 "=============================================================\n" 00988 "=== Configured Devices ======================================\n" 00989 "=============================================================\n" 00990 "===\n"); 00991 00992 i = ao2_iterator_init(pvts, 0); 00993 while ((pvt = ao2_iterator_next(&i))) { 00994 console_pvt_lock(pvt); 00995 00996 ast_cli(a->fd, "=== ---------------------------------------------------------\n" 00997 "=== Device Name: %s\n" 00998 "=== ---> Active: %s\n" 00999 "=== ---> Input Device: %s\n" 01000 "=== ---> Output Device: %s\n" 01001 "=== ---> Context: %s\n" 01002 "=== ---> Extension: %s\n" 01003 "=== ---> CallerID Num: %s\n" 01004 "=== ---> CallerID Name: %s\n" 01005 "=== ---> MOH Interpret: %s\n" 01006 "=== ---> Language: %s\n" 01007 "=== ---> Muted: %s\n" 01008 "=== ---> Auto-Answer: %s\n" 01009 "=== ---> Override Context: %s\n" 01010 "=== ---------------------------------------------------------\n===\n", 01011 pvt->name, (pvt == active_pvt) ? "Yes" : "No", 01012 pvt->input_device, pvt->output_device, pvt->context, 01013 pvt->exten, pvt->cid_num, pvt->cid_name, pvt->mohinterpret, 01014 pvt->language, pvt->muted ? "Yes" : "No", pvt->autoanswer ? "Yes" : "No", 01015 pvt->overridecontext ? "Yes" : "No"); 01016 01017 console_pvt_unlock(pvt); 01018 unref_pvt(pvt); 01019 } 01020 ao2_iterator_destroy(&i); 01021 01022 ast_cli(a->fd, "=============================================================\n\n"); 01023 01024 return CLI_SUCCESS; 01025 }
| static int console_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 521 of file chan_console.c.
References ast_setstate(), AST_STATE_UP, ast_verb, start_stream(), ast_channel::tech_pvt, V_BEGIN, and V_END.
00522 { 00523 struct console_pvt *pvt = c->tech_pvt; 00524 00525 ast_verb(1, V_BEGIN "Call from Console has been Answered" V_END); 00526 00527 ast_setstate(c, AST_STATE_UP); 00528 00529 return start_stream(pvt); 00530 }
| static int console_call | ( | struct ast_channel * | c, | |
| char * | dest, | |||
| int | timeout | |||
| ) | [static] |
Definition at line 559 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.
00560 { 00561 struct ast_frame f = { 0, }; 00562 struct console_pvt *pvt = c->tech_pvt; 00563 00564 ast_verb(1, V_BEGIN "Call to device '%s' on console from '%s' <%s>" V_END, 00565 dest, c->cid.cid_name, c->cid.cid_num); 00566 00567 console_pvt_lock(pvt); 00568 00569 if (pvt->autoanswer) { 00570 pvt->hookstate = 1; 00571 console_pvt_unlock(pvt); 00572 ast_verb(1, V_BEGIN "Auto-answered" V_END); 00573 f.frametype = AST_FRAME_CONTROL; 00574 f.subclass = AST_CONTROL_ANSWER; 00575 } else { 00576 console_pvt_unlock(pvt); 00577 ast_verb(1, V_BEGIN "Type 'console answer' to answer, or use the 'autoanswer' option " 00578 "for future calls" V_END); 00579 f.frametype = AST_FRAME_CONTROL; 00580 f.subclass = AST_CONTROL_RINGING; 00581 ast_indicate(c, AST_CONTROL_RINGING); 00582 } 00583 00584 ast_queue_frame(c, &f); 00585 00586 return start_stream(pvt); 00587 }
| 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 633 of file chan_console.c.
References console_pvt::owner, and ast_channel::tech_pvt.
00634 { 00635 struct console_pvt *pvt = newchan->tech_pvt; 00636 00637 pvt->owner = newchan; 00638 00639 return 0; 00640 }
| static int console_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 506 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.
00507 { 00508 struct console_pvt *pvt = c->tech_pvt; 00509 00510 ast_verb(1, V_BEGIN "Hangup on Console" V_END); 00511 00512 pvt->hookstate = 0; 00513 pvt->owner = NULL; 00514 stop_stream(pvt); 00515 00516 c->tech_pvt = unref_pvt(pvt); 00517 00518 return 0; 00519 }
| static int console_indicate | ( | struct ast_channel * | chan, | |
| int | cond, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Definition at line 598 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.
00599 { 00600 struct console_pvt *pvt = chan->tech_pvt; 00601 int res = 0; 00602 00603 switch (cond) { 00604 case AST_CONTROL_BUSY: 00605 case AST_CONTROL_CONGESTION: 00606 case AST_CONTROL_RINGING: 00607 case -1: 00608 res = -1; /* Ask for inband indications */ 00609 break; 00610 case AST_CONTROL_PROGRESS: 00611 case AST_CONTROL_PROCEEDING: 00612 case AST_CONTROL_VIDUPDATE: 00613 case AST_CONTROL_SRCUPDATE: 00614 break; 00615 case AST_CONTROL_HOLD: 00616 ast_verb(1, V_BEGIN "Console Has Been Placed on Hold" V_END); 00617 ast_moh_start(chan, data, pvt->mohinterpret); 00618 break; 00619 case AST_CONTROL_UNHOLD: 00620 ast_verb(1, V_BEGIN "Console Has Been Retrieved from Hold" V_END); 00621 ast_moh_stop(chan); 00622 break; 00623 default: 00624 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", 00625 cond, chan->name); 00626 /* The core will play inband indications for us if appropriate */ 00627 res = -1; 00628 } 00629 00630 return res; 00631 }
| static struct ast_channel* console_new | ( | struct console_pvt * | pvt, | |
| const char * | ext, | |||
| const char * | ctx, | |||
| int | state | |||
| ) | [static, read] |
Definition at line 414 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().
00415 { 00416 struct ast_channel *chan; 00417 00418 if (!(chan = ast_channel_alloc(1, state, pvt->cid_num, pvt->cid_name, NULL, 00419 ext, ctx, 0, "Console/%s", pvt->name))) { 00420 return NULL; 00421 } 00422 00423 chan->tech = &console_tech; 00424 chan->nativeformats = AST_FORMAT_SLINEAR16; 00425 chan->readformat = AST_FORMAT_SLINEAR16; 00426 chan->writeformat = AST_FORMAT_SLINEAR16; 00427 chan->tech_pvt = ref_pvt(pvt); 00428 00429 pvt->owner = chan; 00430 00431 if (!ast_strlen_zero(pvt->language)) 00432 ast_string_field_set(chan, language, pvt->language); 00433 00434 ast_jb_configure(chan, &global_jbconf); 00435 00436 if (state != AST_STATE_DOWN) { 00437 if (ast_pbx_start(chan)) { 00438 chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION; 00439 ast_hangup(chan); 00440 chan = NULL; 00441 } else 00442 start_stream(pvt); 00443 } 00444 00445 return chan; 00446 }
| static struct ast_frame * console_read | ( | struct ast_channel * | chan | ) | [static, read] |
Definition at line 552 of file chan_console.c.
References ast_debug, and ast_null_frame.
00553 { 00554 ast_debug(1, "I should not be called ...\n"); 00555 00556 return &ast_null_frame; 00557 }
| static struct ast_channel * console_request | ( | const char * | type, | |
| int | format, | |||
| void * | data, | |||
| int * | cause | |||
| ) | [static, read] |
Channel Technology Callbacks
Definition at line 448 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().
00449 { 00450 int oldformat = format; 00451 struct ast_channel *chan = NULL; 00452 struct console_pvt *pvt; 00453 00454 if (!(pvt = find_pvt(data))) { 00455 ast_log(LOG_ERROR, "Console device '%s' not found\n", (char *) data); 00456 return NULL; 00457 } 00458 00459 format &= SUPPORTED_FORMATS; 00460 if (!format) { 00461 ast_log(LOG_NOTICE, "Channel requested with unsupported format(s): '%d'\n", oldformat); 00462 goto return_unref; 00463 } 00464 00465 if (pvt->owner) { 00466 ast_log(LOG_NOTICE, "Console channel already active!\n"); 00467 *cause = AST_CAUSE_BUSY; 00468 goto return_unref; 00469 } 00470 00471 console_pvt_lock(pvt); 00472 chan = console_new(pvt, NULL, NULL, AST_STATE_DOWN); 00473 console_pvt_unlock(pvt); 00474 00475 if (!chan) 00476 ast_log(LOG_WARNING, "Unable to create new Console channel!\n"); 00477 00478 return_unref: 00479 unref_pvt(pvt); 00480 00481 return chan; 00482 }
| 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 589 of file chan_console.c.
References ast_frame::data, ast_frame::samples, console_pvt::stream, and ast_channel::tech_pvt.
00590 { 00591 struct console_pvt *pvt = chan->tech_pvt; 00592 00593 Pa_WriteStream(pvt->stream, f->data, f->samples); 00594 00595 return 0; 00596 }
| 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 246 of file chan_console.c.
References ao2_find(), console_pvt::name, and OBJ_POINTER.
Referenced by build_device(), cli_console_active(), and console_request().
00247 { 00248 struct console_pvt tmp_pvt = { 00249 .name = name, 00250 }; 00251 00252 return ao2_find(pvts, &tmp_pvt, OBJ_POINTER); 00253 }
| static void fini_active_lock | ( | void | ) | [static] |
| static struct console_pvt* get_active_pvt | ( | void | ) | [static, read] |
Definition at line 676 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().
00677 { 00678 struct console_pvt *pvt; 00679 00680 ast_rwlock_rdlock(&active_lock); 00681 pvt = ref_pvt(active_pvt); 00682 ast_rwlock_unlock(&active_lock); 00683 00684 return pvt; 00685 }
| static void init_active_lock | ( | void | ) | [static] |
| 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.
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 pvt_destructor(&globals); 01507 01508 return AST_MODULE_LOAD_DECLINE; 01509 }
| static int open_stream | ( | struct console_pvt * | pvt | ) | [static] |
Definition at line 291 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().
00292 { 00293 int res = paInternalError; 00294 00295 if (!strcasecmp(pvt->input_device, "default") && 00296 !strcasecmp(pvt->output_device, "default")) { 00297 res = Pa_OpenDefaultStream(&pvt->stream, INPUT_CHANNELS, OUTPUT_CHANNELS, 00298 paInt16, SAMPLE_RATE, NUM_SAMPLES, NULL, NULL); 00299 } else { 00300 PaStreamParameters input_params = { 00301 .channelCount = 1, 00302 .sampleFormat = paInt16, 00303 .suggestedLatency = (1.0 / 50.0), /* 20 ms */ 00304 .device = paNoDevice, 00305 }; 00306 PaStreamParameters output_params = { 00307 .channelCount = 1, 00308 .sampleFormat = paInt16, 00309 .suggestedLatency = (1.0 / 50.0), /* 20 ms */ 00310 .device = paNoDevice, 00311 }; 00312 PaDeviceIndex index, num_devices, def_input, def_output; 00313 00314 if (!(num_devices = Pa_GetDeviceCount())) 00315 return res; 00316 00317 def_input = Pa_GetDefaultInputDevice(); 00318 def_output = Pa_GetDefaultOutputDevice(); 00319 00320 for (index = 0; 00321 index < num_devices && (input_params.device == paNoDevice 00322 || output_params.device == paNoDevice); 00323 index++) 00324 { 00325 const PaDeviceInfo *dev = Pa_GetDeviceInfo(index); 00326 00327 if (dev->maxInputChannels) { 00328 if ( (index == def_input && !strcasecmp(pvt->input_device, "default")) || 00329 !strcasecmp(pvt->input_device, dev->name) ) 00330 input_params.device = index; 00331 } 00332 00333 if (dev->maxOutputChannels) { 00334 if ( (index == def_output && !strcasecmp(pvt->output_device, "default")) || 00335 !strcasecmp(pvt->output_device, dev->name) ) 00336 output_params.device = index; 00337 } 00338 } 00339 00340 if (input_params.device == paNoDevice) 00341 ast_log(LOG_ERROR, "No input device found for console device '%s'\n", pvt->name); 00342 if (output_params.device == paNoDevice) 00343 ast_log(LOG_ERROR, "No output device found for console device '%s'\n", pvt->name); 00344 00345 res = Pa_OpenStream(&pvt->stream, &input_params, &output_params, 00346 SAMPLE_RATE, NUM_SAMPLES, paNoFlag, NULL, NULL); 00347 } 00348 00349 return res; 00350 }
| static int pvt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1430 of file chan_console.c.
References CMP_MATCH, and console_pvt::name.
Referenced by load_module(), and load_objects().
01431 { 01432 struct console_pvt *pvt = obj, *pvt2 = arg; 01433 01434 return !strcasecmp(pvt->name, pvt2->name) ? CMP_MATCH : 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(), new_iax(), 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_hash(), and console_pvt::name.
Referenced by load_module(), and load_objects().
01424 { 01425 const struct console_pvt *pvt = obj; 01426 01427 return ast_str_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 233 of file chan_console.c.
References ao2_ref().
Referenced by console_new(), get_active_pvt(), and set_active().
00234 { 00235 if (pvt) 00236 ao2_ref(pvt, +1); 00237 return pvt; 00238 }
| static int reload | ( | void | ) | [static] |
Definition at line 1511 of file chan_console.c.
References load_config().
01512 { 01513 return load_config(1); 01514 }
| static void set_active | ( | struct console_pvt * | pvt, | |
| const char * | value | |||
| ) | [static] |
Definition at line 1132 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().
01133 { 01134 if (pvt == &globals) { 01135 ast_log(LOG_ERROR, "active is only valid as a per-device setting\n"); 01136 return; 01137 } 01138 01139 if (!ast_true(value)) 01140 return; 01141 01142 ast_rwlock_wrlock(&active_lock); 01143 if (active_pvt) 01144 unref_pvt(active_pvt); 01145 active_pvt = ref_pvt(pvt); 01146 ast_rwlock_unlock(&active_lock); 01147 }
| static void set_pvt_defaults | ( | struct console_pvt * | pvt | ) | [static] |
Set default values for a pvt struct.
Definition at line 1234 of file chan_console.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_string_field_set, console_pvt::autoanswer, cid_name, cid_num, context, exten, globals, globals_lock, language, mohinterpret, and console_pvt::overridecontext.
Referenced by build_device(), and load_config().
01235 { 01236 if (pvt == &globals) { 01237 ast_string_field_set(pvt, mohinterpret, "default"); 01238 ast_string_field_set(pvt, context, "default"); 01239 ast_string_field_set(pvt, exten, "s"); 01240 ast_string_field_set(pvt, language, ""); 01241 ast_string_field_set(pvt, cid_num, ""); 01242 ast_string_field_set(pvt, cid_name, ""); 01243 01244 pvt->overridecontext = 0; 01245 pvt->autoanswer = 0; 01246 } else { 01247 ast_mutex_lock(&globals_lock); 01248 01249 ast_string_field_set(pvt, mohinterpret, globals.mohinterpret); 01250 ast_string_field_set(pvt, context, globals.context); 01251 ast_string_field_set(pvt, exten, globals.exten); 01252 ast_string_field_set(pvt, language, globals.language); 01253 ast_string_field_set(pvt, cid_num, globals.cid_num); 01254 ast_string_field_set(pvt, cid_name, globals.cid_name); 01255 01256 pvt->overridecontext = globals.overridecontext; 01257 pvt->autoanswer = globals.autoanswer; 01258 01259 ast_mutex_unlock(&globals_lock); 01260 } 01261 }
| static int start_stream | ( | struct console_pvt * | pvt | ) | [static] |
Definition at line 352 of file chan_console.c.
References ast_debug, ast_log(), ast_pthread_create_background, console_pvt_lock, console_pvt_unlock, LOG_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().
00353 { 00354 PaError res; 00355 int ret_val = 0; 00356 00357 console_pvt_lock(pvt); 00358 00359 if (pvt->streamstate) 00360 goto return_unlock; 00361 00362 pvt->streamstate = 1; 00363 ast_debug(1, "Starting stream\n"); 00364 00365 res = open_stream(pvt); 00366 if (res != paNoError) { 00367 ast_log(LOG_WARNING, "Failed to open stream - (%d) %s\n", 00368 res, Pa_GetErrorText(res)); 00369 ret_val = -1; 00370 goto return_unlock; 00371 } 00372 00373 res = Pa_StartStream(pvt->stream); 00374 if (res != paNoError) { 00375 ast_log(LOG_WARNING, "Failed to start stream - (%d) %s\n", 00376 res, Pa_GetErrorText(res)); 00377 ret_val = -1; 00378 goto return_unlock; 00379 } 00380 00381 if (ast_pthread_create_background(&pvt->thread, NULL, stream_monitor, pvt)) { 00382 ast_log(LOG_ERROR, "Failed to start stream monitor thread\n"); 00383 ret_val = -1; 00384 } 00385 00386 return_unlock: 00387 console_pvt_unlock(pvt); 00388 00389 return ret_val; 00390 }
| static int stop_stream | ( | struct console_pvt * | pvt | ) | [static] |
Definition at line 392 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().
00393 { 00394 if (!pvt->streamstate || pvt->thread == AST_PTHREADT_NULL) 00395 return 0; 00396 00397 pthread_cancel(pvt->thread); 00398 pthread_kill(pvt->thread, SIGURG); 00399 pthread_join(pvt->thread, NULL); 00400 00401 console_pvt_lock(pvt); 00402 Pa_AbortStream(pvt->stream); 00403 Pa_CloseStream(pvt->stream); 00404 pvt->stream = NULL; 00405 pvt->streamstate = 0; 00406 console_pvt_unlock(pvt); 00407 00408 return 0; 00409 }
| 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 1263 of file chan_console.c.
References ast_callerid_split(), ast_string_field_set, cid_name, and cid_num.
Referenced by store_config_core().
01264 { 01265 char cid_name[256]; 01266 char cid_num[256]; 01267 01268 ast_callerid_split(value, cid_name, sizeof(cid_name), 01269 cid_num, sizeof(cid_num)); 01270 01271 ast_string_field_set(pvt, cid_name, cid_name); 01272 ast_string_field_set(pvt, cid_num, cid_num); 01273 }
| 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 1280 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, set_active(), and store_callerid().
Referenced by build_device(), console_cmd(), load_config(), and store_config().
01281 { 01282 if (pvt == &globals && !ast_jb_read_conf(&global_jbconf, var, value)) 01283 return; 01284 01285 CV_START(var, value); 01286 01287 CV_STRFIELD("context", pvt, context); 01288 CV_STRFIELD("extension", pvt, exten); 01289 CV_STRFIELD("mohinterpret", pvt, mohinterpret); 01290 CV_STRFIELD("language", pvt, language); 01291 CV_F("callerid", store_callerid(pvt, value)); 01292 CV_BOOL("overridecontext", pvt->overridecontext); 01293 CV_BOOL("autoanswer", pvt->autoanswer); 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.
Definition at line 265 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().
00266 { 00267 struct console_pvt *pvt = data; 00268 char buf[NUM_SAMPLES * sizeof(int16_t)]; 00269 PaError res; 00270 struct ast_frame f = { 00271 .frametype = AST_FRAME_VOICE, 00272 .subclass = AST_FORMAT_SLINEAR16, 00273 .src = "console_stream_monitor", 00274 .data = buf, 00275 .datalen = sizeof(buf), 00276 .samples = sizeof(buf) / sizeof(int16_t), 00277 }; 00278 00279 for (;;) { 00280 pthread_testcancel(); 00281 res = Pa_ReadStream(pvt->stream, buf, sizeof(buf) / sizeof(int16_t)); 00282 pthread_testcancel(); 00283 00284 if (res == paNoError) 00285 ast_queue_frame(pvt->owner, &f); 00286 } 00287 00288 return NULL; 00289 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 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 240 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().
00241 { 00242 ao2_ref(pvt, -1); 00243 return NULL; 00244 }
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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 1520 of file chan_console.c.
ast_rwlock_t active_lock [static] |
Definition at line 174 of file chan_console.c.
Referenced by destroy_pvts(), get_active_pvt(), and set_active().
struct console_pvt* active_pvt [static] |
Definition at line 173 of file chan_console.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 1520 of file chan_console.c.
struct ast_cli_entry cli_console[] [static] |
Definition at line 1216 of file chan_console.c.
const char config_file[] = "console.conf" [static] |
Definition at line 116 of file chan_console.c.
struct ast_channel_tech console_tech [static] |
Definition at line 210 of file chan_console.c.
struct ast_jb_conf default_jbconf [static] |
Global jitterbuffer configuration.
Definition at line 181 of file chan_console.c.
struct ast_jb_conf global_jbconf [static] |
Definition at line 187 of file chan_console.c.
struct console_pvt globals [static] |
Console pvt structure.
Currently, this is a singleton object. However, multiple instances will be needed when this module is updated for multiple device support.
ast_mutex_t globals_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
struct ao2_container* pvts [static] |
1.5.6