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",
579 ast_debug(9,
"Using a long queue to store audio frames in spy audiohook\n");
593 ast_verb(3,
"Attaching spy channel %s to %s\n",
598 ast_debug(9,
"Using a long queue to store audio frames in whisper audiohook\n");
612 }
else if (
digit ==
'5') {
615 }
else if (
digit ==
'6') {
656 if (!blob || !
type) {
684 const char *spyer_name,
const char *
name,
struct ast_flags *flags)
703 if (!internal_bridge_autochan) {
712 *spyee_bridge_autochan = internal_bridge_autochan;
722 int running = 0, bridge_connected = 0, res, x = 0;
728 const char *spyer_name;
750 memset(&csth, 0,
sizeof(csth));
818 if (!bridge_connected &&
attach_barge(spyee_autochan, &spyee_bridge_autochan,
820 bridge_connected = 1;
827 if (bridge_connected) {
848 if (x ==
sizeof(inp))
866 ast_debug(2,
"Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n",
tmp,
exitcontext);
868 }
else if (res >=
'0' && res <=
'9') {
876 if (res == user_options->
cycle) {
879 }
else if (res == user_options->
exit) {
882 }
else if (res == user_options->
volume) {
928 if (spyee_bridge_autochan) {
940 const size_t pseudo_len = strlen(
"DAHDI/pseudo");
955 return autochan_store;
971 const char *mygroup,
const char *myenforced,
const char *spec,
const char *exten,
972 const char *
context,
const char *
mailbox,
const char *name_context)
976 signed char zero_volume = 0;
979 int num_spied_upon = 1;
1019 ast_debug(2,
"Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n",
tmp,
exitcontext);
1063 ast_debug(2,
"Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n",
tmp,
exitcontext);
1073 prev = autochan->
chan,
1076 next_autochan =
NULL) {
1077 int igrp = !mygroup;
1078 int ienf = !myenforced;
1080 if (autochan->
chan == prev) {
1106 int num_mygroups = 0;
1107 char dup_group[512];
1108 char dup_mygroup[512];
1134 for (y = 0; y < num_mygroups; y++) {
1135 for (
x = 0;
x < num_groups;
x++) {
1136 if (!strcmp(mygroups[y],
groups[
x])) {
1152 snprintf(buffer,
sizeof(buffer) - 1,
":%s:", myenforced);
1157 if ((
end = strchr(
ext,
'-'))) {
1177 strcpy(peer_name,
"spy-");
1181 if ((ptr = strchr(peer_name,
'/'))) {
1183 for (s = peer_name; s < ptr; s++) {
1186 if ((s = strchr(ptr,
'-'))) {
1192 const char *local_context =
S_OR(name_context,
"default");
1195 if (local_mailbox) {
1196 res =
spy_sayname(chan, local_mailbox, local_context);
1217 if (ptr && (num = atoi(ptr))) {
1230 }
else if (res == -2) {
1250 next_autochan =
NULL;
1280 char *myenforced =
NULL;
1281 char *mygroup =
NULL;
1282 char *recbase =
NULL;
1294 char *name_context =
NULL;
1304 if (
args.spec && !strcmp(
args.spec,
"all"))
1315 recbase =
"chanspy";
1319 if (strchr(
"0123456789*#",
tmp) &&
tmp !=
'\0') {
1328 if (strchr(
"0123456789*#",
tmp) &&
tmp !=
'\0') {
1338 if ((sscanf(opts[
OPT_ARG_VOLUME],
"%30d", &vol) != 1) || (vol > 4) || (vol < -4))
1355 *delimiter++ =
'\0';
1356 name_context = delimiter;
1376 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC,
AST_FILE_MODE)) <= 0) {
1382 res =
common_exec(chan, &flags, volfactor, fd, &user_options, mygroup, myenforced,
args.spec,
NULL,
NULL,
mailbox, name_context);
1391 ast_verb(3,
"Stopped spying due to the spied-on channel hanging up.\n");
1399 char *ptr, *exten =
NULL;
1400 char *mygroup =
NULL;
1401 char *recbase =
NULL;
1413 char *name_context =
NULL;
1423 exten =
args.context;
1440 recbase =
"chanspy";
1444 if (strchr(
"0123456789*#",
tmp) &&
tmp !=
'\0') {
1453 if (strchr(
"0123456789*#",
tmp) &&
tmp !=
'\0') {
1463 if ((sscanf(opts[
OPT_ARG_VOLUME],
"%30d", &vol) != 1) || (vol > 4) || (vol < -4))
1477 *delimiter++ =
'\0';
1478 name_context = delimiter;
1500 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC,
AST_FILE_MODE)) <= 0) {
1507 res =
common_exec(chan, &flags, volfactor, fd, &user_options, mygroup,
NULL,
NULL, exten,
args.context,
mailbox, name_context);
1520 const char *spec =
"DAHDI";
1529 char *mygroup =
NULL;
1548 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 start_whispering(struct ast_autochan *autochan, const char *spychan_name, struct ast_audiohook *audiohook, struct ast_flags *flags)
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
int ast_audiohook_set_frame_feed_direction(struct ast_audiohook *audiohook, enum ast_audiohook_direction direction)
Sets direction on audiohook.
"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)