Asterisk - The Open Source Telephony Project  18.5.0
Enumerations | Functions
stasis_app_snoop.h File Reference

Stasis Application Snoop API. See StasisApplication API" for detailed documentation. More...

#include "asterisk/stasis_app.h"
Include dependency graph for stasis_app_snoop.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.


 Directions for audio stream flow. More...


struct ast_channelstasis_app_control_snoop (struct ast_channel *chan, enum stasis_app_snoop_direction spy, enum stasis_app_snoop_direction whisper, const char *app, const char *app_args, const char *snoop_id)
 Create a snoop on the provided channel. More...

Detailed Description

Stasis Application Snoop API. See StasisApplication API" for detailed documentation.

Joshua Colp jcolp[email protected]@dig[email protected]ium.c[email protected]om

Definition in file stasis_app_snoop.h.

Enumeration Type Documentation

◆ stasis_app_snoop_direction

Directions for audio stream flow.


No direction.


Audio stream out to the channel.


Audio stream in from the channel.


Audio stream to AND from the channel.

Definition at line 34 of file stasis_app_snoop.h.

34  {
35  /*! \brief No direction */
37  /*! \brief Audio stream out to the channel */
39  /*! \brief Audio stream in from the channel */
41  /*! \brief Audio stream to AND from the channel */
43 };
Audio stream in from the channel.
Audio stream to AND from the channel.
Audio stream out to the channel.

Function Documentation

◆ stasis_app_control_snoop()

struct ast_channel* stasis_app_control_snoop ( struct ast_channel chan,
enum stasis_app_snoop_direction  spy,
enum stasis_app_snoop_direction  whisper,
const char *  app,
const char *  app_args,
const char *  snoop_id 

Create a snoop on the provided channel.

chanChannel to snoop on.
spyDirection of media that should be spied on.
whisperDirection of media that should be whispered into.
appStasis application to execute on the snoop channel.
app_argsStasis application arguments.
Snoop channel. ast_channel_unref() when done.
NULL if snoop channel couldn't be created.

Definition at line 309 of file res_stasis_snoop.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_ref, ast_atomic_fetchadd_int(), AST_AUDIOHOOK_TYPE_SPY, AST_AUDIOHOOK_TYPE_WHISPER, ast_calloc, ast_channel_alloc, ast_channel_nativeformats_set(), ast_channel_ref, ast_channel_set_fd(), ast_channel_set_rawreadformat(), ast_channel_set_rawwriteformat(), ast_channel_set_readformat(), ast_channel_set_writeformat(), ast_channel_tech_pvt_set(), ast_channel_tech_set(), ast_channel_uniqueid(), ast_channel_unlock, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_get_sample_rate(), AST_FRAME_VOICE, ast_hangup(), ast_pthread_create_detached_background, AST_STATE_UP, ast_str_append(), ast_str_create, ast_str_set(), ast_strlen_zero, ast_timer_fd(), ast_timer_open(), ast_timer_set_rate(), chan_idx, NULL, publish_chanspy_message(), RAII_VAR, snoop_destroy(), snoop_determine_format(), SNOOP_INTERVAL, snoop_setup_audiohook(), snoop_stasis_thread(), STASIS_SNOOP_DIRECTION_NONE, thread, and ast_assigned_ids::uniqueid.

Referenced by ari_channels_handle_snoop_channel().

312 {
313  RAII_VAR(struct stasis_app_snoop *, snoop, NULL, ao2_cleanup);
314  struct ast_format_cap *caps;
315  pthread_t thread;
316  struct ast_assigned_ids assignedids = {
317  .uniqueid = snoop_id,
318  };
322  return NULL;
323  }
326  if (!snoop) {
327  return NULL;
328  }
330  /* Allocate a buffer to store the Stasis application and arguments in */
331  snoop->app = ast_str_create(64);
332  if (!snoop->app) {
333  return NULL;
334  }
336  ast_str_set(&snoop->app, 0, "%s", app);
337  if (!ast_strlen_zero(app_args)) {
338  ast_str_append(&snoop->app, 0, ",%s", app_args);
339  }
341  /* Set up a timer for the Snoop channel so it wakes up at a specific interval */
342  snoop->timer = ast_timer_open();
343  if (!snoop->timer) {
344  return NULL;
345  }
346  ast_timer_set_rate(snoop->timer, 1000 / SNOOP_INTERVAL);
348  /* Determine which signed linear format should be used */
349  snoop_determine_format(chan, snoop);
351  /* Allocate a Snoop channel and set up various parameters */
352  snoop->chan = ast_channel_alloc(1, AST_STATE_UP, "", "", "", "", "", &assignedids, NULL, 0, "Snoop/%s-%08x", ast_channel_uniqueid(chan),
353  (unsigned)ast_atomic_fetchadd_int((int *)&chan_idx, +1));
354  if (!snoop->chan) {
355  return NULL;
356  }
358  /* To keep the channel valid on the Snoop structure until it is destroyed we bump the ref up here */
359  ast_channel_ref(snoop->chan);
361  ast_channel_tech_set(snoop->chan, &snoop_tech);
362  ao2_ref(snoop, +1);
363  ast_channel_tech_pvt_set(snoop->chan, snoop);
364  ast_channel_set_fd(snoop->chan, 0, ast_timer_fd(snoop->timer));
366  /* The format on the Snoop channel will be this signed linear format, and it will never change */
368  if (!caps) {
369  ast_channel_unlock(snoop->chan);
370  ast_hangup(snoop->chan);
371  return NULL;
372  }
373  ast_format_cap_append(caps, snoop->spy_format, 0);
374  ast_channel_nativeformats_set(snoop->chan, caps);
375  ao2_ref(caps, -1);
377  ast_channel_set_writeformat(snoop->chan, snoop->spy_format);
378  ast_channel_set_rawwriteformat(snoop->chan, snoop->spy_format);
379  ast_channel_set_readformat(snoop->chan, snoop->spy_format);
380  ast_channel_set_rawreadformat(snoop->chan, snoop->spy_format);
382  ast_channel_unlock(snoop->chan);
385  if (snoop_setup_audiohook(chan, AST_AUDIOHOOK_TYPE_SPY, spy, &snoop->spy_direction, &snoop->spy)) {
386  ast_hangup(snoop->chan);
387  return NULL;
388  }
390  snoop->spy_samples = ast_format_get_sample_rate(snoop->spy_format) / (1000 / SNOOP_INTERVAL);
391  snoop->spy_active = 1;
393  snoop->silence.frametype = AST_FRAME_VOICE,
394  snoop->silence.datalen = snoop->spy_samples * sizeof(uint16_t),
395  snoop->silence.samples = snoop->spy_samples,
396  snoop->silence.mallocd = 0,
397  snoop->silence.offset = 0,
398  snoop->silence.src = __PRETTY_FUNCTION__,
399  snoop->silence.subclass.format = snoop->spy_format,
400  snoop-> = ast_calloc(snoop->spy_samples, sizeof(uint16_t));
401  if (!snoop-> {
402  ast_hangup(snoop->chan);
403  return NULL;
404  }
405  }
407  /* If whispering is enabled set up the audiohook */
408  if (whisper != STASIS_SNOOP_DIRECTION_NONE) {
409  if (snoop_setup_audiohook(chan, AST_AUDIOHOOK_TYPE_WHISPER, whisper, &snoop->whisper_direction, &snoop->whisper)) {
410  ast_hangup(snoop->chan);
411  return NULL;
412  }
414  snoop->whisper_active = 1;
415  }
417  /* Create the thread which services the Snoop channel */
418  ao2_ref(snoop, +1);
420  ao2_cleanup(snoop);
422  /* No other thread is servicing this channel so we can immediately hang it up */
423  ast_hangup(snoop->chan);
424  return NULL;
425  }
427  /* Keep a reference to the channel we are spying on */
428  snoop->spyee_chan = ast_channel_ref(chan);
430  publish_chanspy_message(snoop, 1);
432  /* The caller of this has a reference as well */
433  return ast_channel_ref(snoop->chan);
434 }
pthread_t thread
Definition: app_meetme.c:1089
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
static void publish_chanspy_message(struct stasis_app_snoop *snoop, int start)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:605
struct ast_timer * ast_timer_open(void)
Open a timer.
Definition: timing.c:122
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
const char * uniqueid
Definition: channel.h:606
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define NULL
Definition: resample.c:96
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:572
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:755
#define ast_strlen_zero(foo)
Definition: strings.h:52
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
Structure which contains all of the snoop information.
static unsigned int chan_idx
Index used to keep Snoop channel names unique.
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
static void * snoop_stasis_thread(void *obj)
Thread used for running the Stasis application.
const char * ast_channel_uniqueid(const struct ast_channel *chan)
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
static struct ast_channel_tech snoop_tech
Channel interface declaration.
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static void snoop_determine_format(struct ast_channel *chan, struct stasis_app_snoop *snoop)
Helper function which gets the format for a Snoop channel based on the channel being snooped on...
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
Definition: timing.c:161
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
Definition: timing.c:166
The interval (in milliseconds) that the Snoop timer is triggered, also controls length of audio withi...
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2431
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
static const char app[]
Definition: app_mysql.c:62
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1259
static int snoop_setup_audiohook(struct ast_channel *chan, enum ast_audiohook_type type, enum stasis_app_snoop_direction requested_direction, enum ast_audiohook_direction *direction, struct ast_audiohook *audiohook)
Internal helper function which sets up and attaches a snoop audiohook.
static void snoop_destroy(void *obj)
Destructor for snoop structure.
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:620