Asterisk - The Open Source Telephony Project GIT-master-7e7a603
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.

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};
@ STASIS_SNOOP_DIRECTION_IN
Audio stream in from the channel.
@ STASIS_SNOOP_DIRECTION_OUT
Audio stream out to the channel.
@ STASIS_SNOOP_DIRECTION_NONE
No direction.
@ STASIS_SNOOP_DIRECTION_BOTH
Audio stream to AND from 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.
snoop_id
Returns
ast_channel ast_channel_unref() when done.
Return values
NULLif snoop channel couldn't be created.

Definition at line 303 of file res_stasis_snoop.c.

306{
307 RAII_VAR(struct stasis_app_snoop *, snoop, NULL, ao2_cleanup);
308 struct ast_format_cap *caps;
309 pthread_t thread;
310 struct ast_assigned_ids assignedids = {
311 .uniqueid = snoop_id,
312 };
313
314 if (spy == STASIS_SNOOP_DIRECTION_NONE &&
315 whisper == STASIS_SNOOP_DIRECTION_NONE) {
316 return NULL;
317 }
318
320 if (!snoop) {
321 return NULL;
322 }
323
324 /* Allocate a buffer to store the Stasis application and arguments in */
325 snoop->app = ast_str_create(64);
326 if (!snoop->app) {
327 return NULL;
328 }
329
330 ast_str_set(&snoop->app, 0, "%s", app);
331 if (!ast_strlen_zero(app_args)) {
332 ast_str_append(&snoop->app, 0, ",%s", app_args);
333 }
334
335 /* Set up a timer for the Snoop channel so it wakes up at a specific interval */
336 snoop->timer = ast_timer_open();
337 if (!snoop->timer) {
338 return NULL;
339 }
340 ast_timer_set_rate(snoop->timer, 1000 / SNOOP_INTERVAL);
341
342 /* Determine which signed linear format should be used */
343 snoop_determine_format(chan, snoop);
344
345 /* Allocate a Snoop channel and set up various parameters */
346 snoop->chan = ast_channel_alloc(1, AST_STATE_UP, "", "", "", "", "", &assignedids, NULL, 0, "Snoop/%s-%08x", ast_channel_uniqueid(chan),
347 (unsigned)ast_atomic_fetchadd_int((int *)&chan_idx, +1));
348 if (!snoop->chan) {
349 return NULL;
350 }
351
352 /* To keep the channel valid on the Snoop structure until it is destroyed we bump the ref up here */
353 ast_channel_ref(snoop->chan);
354
355 ast_channel_tech_set(snoop->chan, &snoop_tech);
356 ao2_ref(snoop, +1);
357 ast_channel_tech_pvt_set(snoop->chan, snoop);
358 ast_channel_set_fd(snoop->chan, 0, ast_timer_fd(snoop->timer));
359
360 /* The format on the Snoop channel will be this signed linear format, and it will never change */
362 if (!caps) {
363 ast_channel_unlock(snoop->chan);
364 ast_hangup(snoop->chan);
365 return NULL;
366 }
367 ast_format_cap_append(caps, snoop->spy_format, 0);
368 ast_channel_nativeformats_set(snoop->chan, caps);
369 ao2_ref(caps, -1);
370
371 ast_channel_set_writeformat(snoop->chan, snoop->spy_format);
372 ast_channel_set_rawwriteformat(snoop->chan, snoop->spy_format);
373 ast_channel_set_readformat(snoop->chan, snoop->spy_format);
374 ast_channel_set_rawreadformat(snoop->chan, snoop->spy_format);
375
376 ast_channel_unlock(snoop->chan);
377
378 if (spy != STASIS_SNOOP_DIRECTION_NONE) {
379 if (snoop_setup_audiohook(chan, AST_AUDIOHOOK_TYPE_SPY, spy, &snoop->spy_direction, &snoop->spy)) {
380 ast_hangup(snoop->chan);
381 return NULL;
382 }
383
384 snoop->spy_samples = ast_format_get_sample_rate(snoop->spy_format) / (1000 / SNOOP_INTERVAL);
385 snoop->spy_active = 1;
386
387 snoop->silence.frametype = AST_FRAME_VOICE,
388 snoop->silence.datalen = snoop->spy_samples * sizeof(uint16_t),
389 snoop->silence.samples = snoop->spy_samples,
390 snoop->silence.mallocd = 0,
391 snoop->silence.offset = 0,
392 snoop->silence.src = __PRETTY_FUNCTION__,
393 snoop->silence.subclass.format = snoop->spy_format,
394 snoop->silence.data.ptr = ast_calloc(snoop->spy_samples, sizeof(uint16_t));
395 if (!snoop->silence.data.ptr) {
396 ast_hangup(snoop->chan);
397 return NULL;
398 }
399 }
400
401 /* If whispering is enabled set up the audiohook */
402 if (whisper != STASIS_SNOOP_DIRECTION_NONE) {
403 if (snoop_setup_audiohook(chan, AST_AUDIOHOOK_TYPE_WHISPER, whisper, &snoop->whisper_direction, &snoop->whisper)) {
404 ast_hangup(snoop->chan);
405 return NULL;
406 }
407
408 snoop->whisper_active = 1;
409 }
410
411 /* Create the thread which services the Snoop channel */
412 ao2_ref(snoop, +1);
414 ao2_cleanup(snoop);
415
416 /* No other thread is servicing this channel so we can immediately hang it up */
417 ast_hangup(snoop->chan);
418 return NULL;
419 }
420
421 /* Keep a reference to the channel we are spying on */
422 snoop->spyee_chan = ast_channel_ref(chan);
423
424 publish_chanspy_message(snoop, 1);
425
426 /* The caller of this has a reference as well */
427 return ast_channel_ref(snoop->chan);
428}
static const char app[]
Definition: app_adsiprog.c:56
pthread_t thread
Definition: app_sla.c:329
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
@ AST_AUDIOHOOK_TYPE_SPY
Definition: audiohook.h:36
@ AST_AUDIOHOOK_TYPE_WHISPER
Definition: audiohook.h:37
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1258
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
const char * ast_channel_uniqueid(const struct ast_channel *chan)
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2426
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
@ AST_STATE_UP
Definition: channelstate.h:42
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
@ AST_FRAME_VOICE
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:757
static void publish_chanspy_message(struct stasis_app_snoop *snoop, int start)
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.
static void * snoop_stasis_thread(void *obj)
Thread used for running the Stasis application.
static struct ast_channel_tech snoop_tech
Channel interface declaration.
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.
static unsigned int chan_idx
Index used to keep Snoop channel names unique.
#define SNOOP_INTERVAL
The interval (in milliseconds) that the Snoop timer is triggered, also controls length of audio withi...
#define NULL
Definition: resample.c:96
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:1139
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
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:1113
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:604
const char * uniqueid
Definition: channel.h:605
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Structure which contains all of the snoop information.
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
Definition: timing.c:166
struct ast_timer * ast_timer_open(void)
Open a timer.
Definition: timing.c:122
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
Definition: timing.c:161
#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:941
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:597

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_ref, app, 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(), snoop_tech, STASIS_SNOOP_DIRECTION_NONE, thread, and ast_assigned_ids::uniqueid.

Referenced by ari_channels_handle_snoop_channel().