60#define AST_NAME_STRLEN 256
61#define NUM_SPYGROUPS 128
491 .datalen =
sizeof(stereo_buf),
502 memcpy(read_buf, fr_read->
data.
ptr,
sizeof(read_buf));
505 memset(read_buf, 0,
sizeof(read_buf));
514 for (i = 0; i <
samples; i++) {
515 stereo_buf[i*2] = read_buf[i];
519 stereo_frame.
data.
ptr = stereo_buf;
569 ast_verb(3,
"Attaching spy channel %s to %s\n",
578 ast_debug(9,
"Using a long queue to store audio frames in spy audiohook\n");
592 }
else if (
digit ==
'5') {
595 }
else if (
digit ==
'6') {
636 if (!blob || !
type) {
664 const char *spyer_name,
const char *
name,
struct ast_flags *flags)
683 if (!internal_bridge_autochan) {
687 if (
start_spying(internal_bridge_autochan, spyer_name, bridge_whisper_audiohook,
flags)) {
692 *spyee_bridge_autochan = internal_bridge_autochan;
702 int running = 0, bridge_connected = 0, res, x = 0;
708 const char *spyer_name;
730 memset(&csth, 0,
sizeof(csth));
798 if (!bridge_connected &&
attach_barge(spyee_autochan, &spyee_bridge_autochan,
800 bridge_connected = 1;
807 if (bridge_connected) {
828 if (x ==
sizeof(inp))
846 ast_debug(2,
"Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n",
tmp,
exitcontext);
848 }
else if (res >=
'0' && res <=
'9') {
856 if (res == user_options->
cycle) {
859 }
else if (res == user_options->
exit) {
862 }
else if (res == user_options->
volume) {
908 if (spyee_bridge_autochan) {
920 const size_t pseudo_len = strlen(
"DAHDI/pseudo");
935 return autochan_store;
951 const char *mygroup,
const char *myenforced,
const char *spec,
const char *exten,
952 const char *
context,
const char *
mailbox,
const char *name_context)
956 signed char zero_volume = 0;
959 int num_spied_upon = 1;
999 ast_debug(2,
"Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n",
tmp,
exitcontext);
1043 ast_debug(2,
"Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n",
tmp,
exitcontext);
1053 prev = autochan->
chan,
1056 next_autochan =
NULL) {
1057 int igrp = !mygroup;
1058 int ienf = !myenforced;
1060 if (autochan->
chan == prev) {
1086 int num_mygroups = 0;
1087 char dup_group[512];
1088 char dup_mygroup[512];
1114 for (y = 0; y < num_mygroups; y++) {
1115 for (
x = 0;
x < num_groups;
x++) {
1116 if (!strcmp(mygroups[y],
groups[
x])) {
1132 snprintf(buffer,
sizeof(buffer) - 1,
":%s:", myenforced);
1137 if ((
end = strchr(
ext,
'-'))) {
1157 strcpy(peer_name,
"spy-");
1161 if ((ptr = strchr(peer_name,
'/'))) {
1163 for (s = peer_name; s < ptr; s++) {
1166 if ((s = strchr(ptr,
'-'))) {
1172 const char *local_context =
S_OR(name_context,
"default");
1175 if (local_mailbox) {
1176 res =
spy_sayname(chan, local_mailbox, local_context);
1197 if (ptr && (num = atoi(ptr))) {
1210 }
else if (res == -2) {
1230 next_autochan =
NULL;
1260 char *myenforced =
NULL;
1261 char *mygroup =
NULL;
1262 char *recbase =
NULL;
1274 char *name_context =
NULL;
1284 if (
args.spec && !strcmp(
args.spec,
"all"))
1295 recbase =
"chanspy";
1299 if (strchr(
"0123456789*#",
tmp) &&
tmp !=
'\0') {
1308 if (strchr(
"0123456789*#",
tmp) &&
tmp !=
'\0') {
1318 if ((sscanf(opts[
OPT_ARG_VOLUME],
"%30d", &vol) != 1) || (vol > 4) || (vol < -4))
1335 *delimiter++ =
'\0';
1336 name_context = delimiter;
1356 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC,
AST_FILE_MODE)) <= 0) {
1362 res =
common_exec(chan, &flags, volfactor, fd, &user_options, mygroup, myenforced,
args.spec,
NULL,
NULL,
mailbox, name_context);
1371 ast_verb(3,
"Stopped spying due to the spied-on channel hanging up.\n");
1379 char *ptr, *exten =
NULL;
1380 char *mygroup =
NULL;
1381 char *recbase =
NULL;
1393 char *name_context =
NULL;
1403 exten =
args.context;
1420 recbase =
"chanspy";
1424 if (strchr(
"0123456789*#",
tmp) &&
tmp !=
'\0') {
1433 if (strchr(
"0123456789*#",
tmp) &&
tmp !=
'\0') {
1443 if ((sscanf(opts[
OPT_ARG_VOLUME],
"%30d", &vol) != 1) || (vol > 4) || (vol < -4))
1457 *delimiter++ =
'\0';
1458 name_context = delimiter;
1480 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC,
AST_FILE_MODE)) <= 0) {
1487 res =
common_exec(chan, &flags, volfactor, fd, &user_options, mygroup,
NULL,
NULL, exten,
args.context,
mailbox, name_context);
1500 const char *spec =
"DAHDI";
1509 char *mygroup =
NULL;
1528 res =
common_exec(chan, &flags, 0, 0, &user_options, mygroup,
NULL, spec,
NULL,
NULL,
NULL,
NULL);
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)
@ OPTION_DTMF_SWITCH_MODES
static void * spy_alloc(struct ast_channel *chan, void *data)
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 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 struct ast_autochan * next_channel(struct ast_channel_iterator *iter, struct ast_channel *chan)
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)
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_all(struct ast_audiohook *audiohook, size_t samples, struct ast_format *format, struct ast_frame **read_frame, struct ast_frame **write_frame)
Reads a frame in from the audiohook structure in mixed audio mode and copies read and write frame dat...
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.
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_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
struct ast_autochan * ast_autochan_setup(struct ast_channel *chan)
set up a new ast_autochan structure
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.
#define ast_autochan_channel_unlock(autochan)
General Asterisk PBX channel definitions.
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
const char * ast_channel_name(const struct ast_channel *chan)
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_channel_iterator * ast_channel_iterator_by_name_new(const char *name, size_t name_len)
Create a new channel iterator based on name.
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
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.
#define ast_channel_lock(chan)
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
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.
const char * ast_channel_uniqueid(const struct ast_channel *chan)
const char * ast_channel_context(const struct ast_channel *chan)
void ast_deactivate_generator(struct ast_channel *chan)
struct ast_channel_iterator * ast_channel_iterator_by_exten_new(const char *exten, const char *context)
Create a new channel iterator based on extension.
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.
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
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.
#define ast_channel_unref(c)
Decrease channel reference count.
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
const char * ast_channel_language(const struct ast_channel *chan)
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
#define ast_channel_cleanup(c)
Cleanup a channel reference.
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
int ast_answer(struct ast_channel *chan)
Answer a channel.
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
#define ast_channel_unlock(chan)
ast_channel_state
ast_channel states
void write_buf(int file, char *buffer, int num)
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 ast_multi_channel_blob * ast_multi_channel_blob_create(struct ast_json *blob)
Create a ast_multi_channel_blob suitable for a stasis_message.
struct stasis_message_type * ast_channel_chanspy_start_type(void)
Message type for when a channel starts spying on another channel.
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,...
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.
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 *)
void ast_frame_free(struct ast_frame *frame, int cache)
Frees a frame or list of frames.
#define ast_frdup(fr)
Copies a frame.
#define AST_OPTION_TXGAIN
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)
Asterisk JSON abstraction layer.
struct ast_json * ast_json_null(void)
Get the JSON null value.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
#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.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
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)
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.
char exten[AST_MAX_EXTENSION]
Structure used to handle boolean flags.
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 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)