60 #define AST_NAME_STRLEN 256
61 #define NUM_SPYGROUPS 128
512 ast_verb(3,
"Attaching spy channel %s to %s\n",
521 ast_debug(9,
"Using a long queue to store audio frames in spy audiohook\n");
535 }
else if (
digit ==
'5') {
538 }
else if (
digit ==
'6') {
579 if (!blob || !
type) {
607 const char *spyer_name,
const char *
name,
struct ast_flags *flags)
626 if (!internal_bridge_autochan) {
630 if (
start_spying(internal_bridge_autochan, spyer_name, bridge_whisper_audiohook,
flags)) {
635 *spyee_bridge_autochan = internal_bridge_autochan;
645 int running = 0, bridge_connected = 0, res, x = 0;
651 const char *spyer_name;
673 memset(&csth, 0,
sizeof(csth));
741 if (!bridge_connected &&
attach_barge(spyee_autochan, &spyee_bridge_autochan,
743 bridge_connected = 1;
750 if (bridge_connected) {
771 if (x ==
sizeof(inp))
789 ast_debug(2,
"Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n",
tmp,
exitcontext);
791 }
else if (res >=
'0' && res <=
'9') {
799 if (res == user_options->
cycle) {
802 }
else if (res == user_options->
exit) {
805 }
else if (res == user_options->
volume) {
851 if (spyee_bridge_autochan) {
863 const size_t pseudo_len = strlen(
"DAHDI/pseudo");
878 return autochan_store;
894 const char *mygroup,
const char *myenforced,
const char *spec,
const char *
exten,
895 const char *
context,
const char *
mailbox,
const char *name_context)
899 signed char zero_volume = 0;
902 int num_spied_upon = 1;
944 ast_debug(2,
"Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n",
tmp,
exitcontext);
988 ast_debug(2,
"Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n",
tmp,
exitcontext);
998 prev = autochan->
chan,
1001 next_autochan =
NULL) {
1002 int igrp = !mygroup;
1003 int ienf = !myenforced;
1005 if (autochan->
chan == prev) {
1031 int num_mygroups = 0;
1032 char dup_group[512];
1033 char dup_mygroup[512];
1059 for (y = 0; y < num_mygroups; y++) {
1060 for (
x = 0;
x < num_groups;
x++) {
1061 if (!strcmp(mygroups[y],
groups[
x])) {
1077 snprintf(buffer,
sizeof(buffer) - 1,
":%s:", myenforced);
1082 if ((
end = strchr(
ext,
'-'))) {
1102 strcpy(peer_name,
"spy-");
1106 if ((ptr = strchr(peer_name,
'/'))) {
1108 for (s = peer_name; s < ptr; s++) {
1111 if ((s = strchr(ptr,
'-'))) {
1117 const char *local_context =
S_OR(name_context,
"default");
1120 if (local_mailbox) {
1121 res =
spy_sayname(chan, local_mailbox, local_context);
1142 if (ptr && (num = atoi(ptr))) {
1155 }
else if (res == -2) {
1175 next_autochan =
NULL;
1205 char *myenforced =
NULL;
1206 char *mygroup =
NULL;
1207 char *recbase =
NULL;
1219 char *name_context =
NULL;
1229 if (
args.spec && !strcmp(
args.spec,
"all"))
1240 recbase =
"chanspy";
1244 if (strchr(
"0123456789*#",
tmp) &&
tmp !=
'\0') {
1253 if (strchr(
"0123456789*#",
tmp) &&
tmp !=
'\0') {
1263 if ((sscanf(opts[
OPT_ARG_VOLUME],
"%30d", &vol) != 1) || (vol > 4) || (vol < -4))
1280 *delimiter++ =
'\0';
1281 name_context = delimiter;
1301 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC,
AST_FILE_MODE)) <= 0) {
1307 res =
common_exec(chan, &flags, volfactor, fd, &user_options, mygroup, myenforced,
args.spec,
NULL,
NULL,
mailbox, name_context);
1316 ast_verb(3,
"Stopped spying due to the spied-on channel hanging up.\n");
1325 char *mygroup =
NULL;
1326 char *recbase =
NULL;
1338 char *name_context =
NULL;
1365 recbase =
"chanspy";
1369 if (strchr(
"0123456789*#",
tmp) &&
tmp !=
'\0') {
1378 if (strchr(
"0123456789*#",
tmp) &&
tmp !=
'\0') {
1388 if ((sscanf(opts[
OPT_ARG_VOLUME],
"%30d", &vol) != 1) || (vol > 4) || (vol < -4))
1402 *delimiter++ =
'\0';
1403 name_context = delimiter;
1425 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC,
AST_FILE_MODE)) <= 0) {
1432 res =
common_exec(chan, &flags, volfactor, fd, &user_options, mygroup,
NULL,
NULL,
exten,
args.context,
mailbox, name_context);
1445 const char *spec =
"DAHDI";
1454 char *mygroup =
NULL;
1473 res =
common_exec(chan, &flags, 0, 0, &user_options, mygroup,
NULL, spec,
NULL,
NULL,
NULL,
NULL);
static void * spy_alloc(struct ast_channel *chan, void *data)
static int spy_sayname(struct ast_channel *chan, const char *mailbox, const char *context)
static int chanspy_exec(struct ast_channel *chan, const char *data)
static void publish_chanspy_message(struct ast_channel *spyer, struct ast_channel *spyee, int start)
static int pack_channel_into_message(struct ast_channel *chan, const char *role, struct ast_multi_channel_blob *payload)
static int dahdiscan_exec(struct ast_channel *chan, const char *data)
static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_autochan, int *volfactor, int fd, struct spy_dtmf_options *user_options, struct ast_flags *flags, char *exitcontext)
static struct ast_autochan * next_channel(struct ast_channel_iterator *iter, struct ast_channel *chan)
static void change_spy_mode(const char digit, struct ast_flags *flags)
static const struct ast_app_option spy_opts[128]
static int common_exec(struct ast_channel *chan, struct ast_flags *flags, int volfactor, const int fd, struct spy_dtmf_options *user_options, const char *mygroup, const char *myenforced, const char *spec, const char *exten, const char *context, const char *mailbox, const char *name_context)
static int extenspy_exec(struct ast_channel *chan, const char *data)
static const char app_dahdiscan[]
static int start_spying(struct ast_autochan *autochan, const char *spychan_name, struct ast_audiohook *audiohook, struct ast_flags *flags)
@ OPTION_DTMF_SWITCH_MODES
static int load_module(void)
static int attach_barge(struct ast_autochan *spyee_autochan, struct ast_autochan **spyee_bridge_autochan, struct ast_audiohook *bridge_whisper_audiohook, const char *spyer_name, const char *name, struct ast_flags *flags)
static const char app_ext[]
static int unload_module(void)
static void spy_release(struct ast_channel *chan, void *data)
static const char app_chan[]
static int spy_generate(struct ast_channel *chan, void *data, int len, int samples)
static struct ast_generator spygen
static char exitcontext[AST_MAX_CONTEXT]
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
struct ast_frame * ast_audiohook_read_frame(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, struct ast_format *format)
Reads a frame in from the audiohook structure.
int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source, enum ast_audiohook_init_flags flags)
Initialize an audiohook structure.
int ast_audiohook_write_frame(struct ast_audiohook *audiohook, enum ast_audiohook_direction direction, struct ast_frame *frame)
Writes a frame into the audiohook structure.
@ AST_AUDIOHOOK_DIRECTION_READ
@ AST_AUDIOHOOK_DIRECTION_WRITE
@ AST_AUDIOHOOK_DIRECTION_BOTH
#define ast_audiohook_lock(ah)
Lock an audiohook.
@ AST_AUDIOHOOK_MUTE_WRITE
@ AST_AUDIOHOOK_SMALL_QUEUE
@ AST_AUDIOHOOK_TRIGGER_SYNC
int ast_audiohook_detach(struct ast_audiohook *audiohook)
Detach audiohook from channel.
int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
Attach audiohook to channel.
int ast_audiohook_destroy(struct ast_audiohook *audiohook)
Destroys an audiohook structure.
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
@ AST_AUDIOHOOK_TYPE_WHISPER
@ AST_AUDIOHOOK_STATUS_RUNNING
"smart" channels that update automatically if a channel is masqueraded
void ast_autochan_destroy(struct ast_autochan *autochan)
destroy an ast_autochan structure
#define ast_autochan_channel_lock(autochan)
Lock the autochan's channel lock.
struct ast_autochan * ast_autochan_setup(struct ast_channel *chan)
set up a new ast_autochan structure
#define ast_autochan_channel_unlock(autochan)
static char exten[AST_MAX_EXTENSION]
static char context[AST_MAX_CONTEXT]
static void parse(struct mgcp_request *req)
static char mailbox[AST_MAX_MAILBOX_UNIQUEID]
General Asterisk PBX channel definitions.
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
struct ast_channel_iterator * ast_channel_iterator_by_name_new(const char *name, size_t name_len)
Create a new channel iterator based on name.
int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define ast_channel_lock(chan)
const char * ast_channel_context(const struct ast_channel *chan)
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
Stops a previously-started silence generator on the given channel.
#define ast_channel_ref(c)
Increase channel reference count.
void ast_deactivate_generator(struct ast_channel *chan)
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
const char * ast_channel_language(const struct ast_channel *chan)
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
Set a flag on a channel.
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
#define ast_channel_unref(c)
Decrease channel reference count.
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
struct ast_channel_iterator * ast_channel_iterator_by_exten_new(const char *exten, const char *context)
Create a new channel iterator based on extension.
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
const char * ast_channel_macrocontext(const struct ast_channel *chan)
#define ast_channel_cleanup(c)
Cleanup a channel reference.
int ast_answer(struct ast_channel *chan)
Answer a channel.
#define ast_channel_unlock(chan)
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
ast_channel_state
ast_channel states
Call Parking and Pickup API Includes code and algorithms from the Zapata library.
Generic File Format Support. Should be included by clients of the file handling routines....
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct stasis_message_type * ast_channel_chanspy_stop_type(void)
Message type for when a channel stops spying on another channel.
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
struct stasis_message_type * ast_channel_chanspy_start_type(void)
Message type for when a channel starts spying on another channel.
void ast_multi_channel_blob_add_channel(struct ast_multi_channel_blob *obj, const char *role, struct ast_channel_snapshot *snapshot)
Add a ast_channel_snapshot to a ast_multi_channel_blob object.
struct ast_multi_channel_blob * ast_multi_channel_blob_create(struct ast_json *blob)
Create a ast_multi_channel_blob suitable for a stasis_message.
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
#define ast_app_separate_args(a, b, c, d)
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
int ast_app_sayname(struct ast_channel *chan, const char *mailbox_id)
Play a recorded user name for the mailbox to the specified channel.
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
char * strcasestr(const char *, const char *)
#define AST_OPTION_TXGAIN
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)
Asterisk JSON abstraction layer.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
struct ast_json * ast_json_null(void)
Get the JSON null value.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Asterisk locking-related definitions:
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
#define ASTERISK_GPL_KEY
The text the key() function should return.
int ast_unregister_application(const char *app)
Unregister an application.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Options provided by main asterisk program.
Asterisk file paths, configured in asterisk.conf.
const char * ast_config_AST_MONITOR_DIR
Core PBX routines and definitions.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
int ast_goto_if_exists(struct ast_channel *chan, const char *context, const char *exten, int priority)
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Say numbers and dates (maybe words one day too)
int ast_say_character_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity)
function to pronounce character and phonetic strings
int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang)
says digits
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
struct ast_audiohook_options options
enum ast_audiohook_status status
struct ast_channel * chan
struct ast_autochan * next
Structure representing a snapshot of channel state.
Main Channel structure associated with a channel.
Structure used to handle boolean flags.
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@254 data
enum ast_frame_type frametype
void *(* alloc)(struct ast_channel *chan, void *params)
Abstract JSON element (object, array, string, int, ...).
A multi channel blob data structure for multi_channel_blob stasis messages.
struct ast_audiohook bridge_whisper_audiohook
struct ast_audiohook whisper_audiohook
struct ast_audiohook spy_audiohook
Support for translation of data formats. translate.c.
#define ast_test_flag(p, flag)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define ast_clear_flag(p, flag)
#define ast_set_flag(p, flag)
#define ast_copy_flags(dest, src, flagz)