Asterisk - The Open Source Telephony Project  GIT-master-e8cda4b
Enumerations | Functions
stasis_app_snoop.h File Reference

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

#include "asterisk/stasis_app.h"

Go to the source code of this file.

Enumerations

enum  stasis_app_snoop_direction { STASIS_SNOOP_DIRECTION_NONE = 0, STASIS_SNOOP_DIRECTION_OUT, STASIS_SNOOP_DIRECTION_IN, STASIS_SNOOP_DIRECTION_BOTH }
 Directions for audio stream flow. More...
 

Functions

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.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om
Since
12

Definition in file stasis_app_snoop.h.

Enumeration Type Documentation

◆ stasis_app_snoop_direction

Directions for audio stream flow.

Enumerator
STASIS_SNOOP_DIRECTION_NONE 

No direction.

STASIS_SNOOP_DIRECTION_OUT 

Audio stream out to the channel.

STASIS_SNOOP_DIRECTION_IN 

Audio stream in from the channel.

STASIS_SNOOP_DIRECTION_BOTH 

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.

Parameters
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.
Returns
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  };
319 
320  if (spy == STASIS_SNOOP_DIRECTION_NONE &&
321  whisper == STASIS_SNOOP_DIRECTION_NONE) {
322  return NULL;
323  }
324 
326  if (!snoop) {
327  return NULL;
328  }
329 
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  }
335 
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  }
340 
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);
347 
348  /* Determine which signed linear format should be used */
349  snoop_determine_format(chan, snoop);
350 
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  }
357 
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);
360 
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));
365 
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);
376 
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);
381 
382  ast_channel_unlock(snoop->chan);
383 
384  if (spy != STASIS_SNOOP_DIRECTION_NONE) {
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  }
389 
390  snoop->spy_samples = ast_format_get_sample_rate(snoop->spy_format) / (1000 / SNOOP_INTERVAL);
391  snoop->spy_active = 1;
392 
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->silence.data.ptr = ast_calloc(snoop->spy_samples, sizeof(uint16_t));
401  if (!snoop->silence.data.ptr) {
402  ast_hangup(snoop->chan);
403  return NULL;
404  }
405  }
406 
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  }
413 
414  snoop->whisper_active = 1;
415  }
416 
417  /* Create the thread which services the Snoop channel */
418  ao2_ref(snoop, +1);
420  ao2_cleanup(snoop);
421 
422  /* No other thread is servicing this channel so we can immediately hang it up */
423  ast_hangup(snoop->chan);
424  return NULL;
425  }
426 
427  /* Keep a reference to the channel we are spying on */
428  snoop->spyee_chan = ast_channel_ref(chan);
429 
430  publish_chanspy_message(snoop, 1);
431 
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
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_strlen_zero(a)
Definition: muted.c:73
#define ast_channel_unlock(chan)
Definition: channel.h:2914
#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:2544
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
#define SNOOP_INTERVAL
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:2427
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2938
#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