Asterisk - The Open Source Telephony Project GIT-master-a358458
Data Structures | Macros | Functions | Variables
res_stasis_snoop.c File Reference

Stasis application snoop control support. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/stasis_app_impl.h"
#include "asterisk/stasis_app_snoop.h"
#include "asterisk/audiohook.h"
#include "asterisk/pbx.h"
#include "asterisk/timing.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/json.h"
#include "asterisk/format_cache.h"
Include dependency graph for res_stasis_snoop.c:

Go to the source code of this file.

Data Structures

struct  stasis_app_snoop
 Structure which contains all of the snoop information. More...
 

Macros

#define SNOOP_INTERVAL   20
 The interval (in milliseconds) that the Snoop timer is triggered, also controls length of audio within frames. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int load_module (void)
 
static void publish_chanspy_message (struct stasis_app_snoop *snoop, int start)
 
static void snoop_destroy (void *obj)
 Destructor for snoop structure. More...
 
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. More...
 
static int snoop_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 
static int snoop_hangup (struct ast_channel *chan)
 Callback function for hanging up a Snoop channel. More...
 
static struct ast_framesnoop_read (struct ast_channel *chan)
 Callback function for reading from a Snoop channel. More...
 
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. More...
 
static void * snoop_stasis_thread (void *obj)
 Thread used for running the Stasis application. More...
 
static int snoop_write (struct ast_channel *chan, struct ast_frame *frame)
 Callback function for writing to a Snoop whisper audiohook. 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...
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Stasis application snoop support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .requires = "res_stasis", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static unsigned int chan_idx
 Index used to keep Snoop channel names unique. More...
 
static struct ast_channel_tech snoop_tech
 Channel interface declaration. More...
 

Detailed Description

Stasis application snoop control support.

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

Definition in file res_stasis_snoop.c.

Macro Definition Documentation

◆ SNOOP_INTERVAL

#define SNOOP_INTERVAL   20

The interval (in milliseconds) that the Snoop timer is triggered, also controls length of audio within frames.

Definition at line 44 of file res_stasis_snoop.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 445 of file res_stasis_snoop.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 445 of file res_stasis_snoop.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 445 of file res_stasis_snoop.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 430 of file res_stasis_snoop.c.

431{
433}
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70

References AST_MODULE_LOAD_SUCCESS.

◆ publish_chanspy_message()

static void publish_chanspy_message ( struct stasis_app_snoop snoop,
int  start 
)
static

Definition at line 113 of file res_stasis_snoop.c.

114{
115 RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
116 RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
118 RAII_VAR(struct ast_channel_snapshot *, snoop_snapshot, NULL, ao2_cleanup);
119 RAII_VAR(struct ast_channel_snapshot *, spyee_snapshot, NULL, ao2_cleanup);
121
122 blob = ast_json_null();
123 if (!blob || !type) {
124 return;
125 }
126
127 payload = ast_multi_channel_blob_create(blob);
128 if (!payload) {
129 return;
130 }
131
133 if (!snoop_snapshot) {
134 return;
135 }
136 ast_multi_channel_blob_add_channel(payload, "spyer_channel", snoop_snapshot);
137
138 if (snoop->spyee_chan) {
142 if (spyee_snapshot) {
143 ast_multi_channel_blob_add_channel(payload, "spyee_channel", spyee_snapshot);
144 }
145 }
146
148 if (!message) {
149 return;
150 }
151
153}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
static const char type[]
Definition: chan_ooh323.c:109
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)
Definition: channel.h:2922
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
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.
struct ast_json * ast_json_null(void)
Get the JSON null value.
Definition: json.c:248
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define NULL
Definition: resample.c:96
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.
Definition: stasis.c:1511
Structure representing a snapshot of channel state.
Abstract JSON element (object, array, string, int, ...).
A multi channel blob data structure for multi_channel_blob stasis messages.
struct ast_channel * chan
Snoop channel.
struct ast_channel * spyee_chan
The channel that the Snoop channel is snooping on.
#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

References ao2_cleanup, ast_channel_chanspy_start_type(), ast_channel_chanspy_stop_type(), ast_channel_lock, ast_channel_snapshot_get_latest(), ast_channel_topic(), ast_channel_uniqueid(), ast_channel_unlock, ast_json_null(), ast_json_unref(), ast_multi_channel_blob_add_channel(), ast_multi_channel_blob_create(), stasis_app_snoop::chan, NULL, RAII_VAR, stasis_app_snoop::spyee_chan, stasis_message_create(), stasis_publish(), and type.

Referenced by snoop_hangup(), and stasis_app_control_snoop().

◆ snoop_destroy()

static void snoop_destroy ( void *  obj)
static

Destructor for snoop structure.

Definition at line 80 of file res_stasis_snoop.c.

81{
82 struct stasis_app_snoop *snoop = obj;
83
84 if (snoop->timer) {
85 ast_timer_close(snoop->timer);
86 }
87
88 if (snoop->spy_active) {
90 }
91
92 if (snoop->whisper_active) {
94 }
95
96 if (snoop->silence.data.ptr) {
97 ast_free(snoop->silence.data.ptr);
98 snoop->silence.data.ptr = NULL;
99 }
100
101 ast_free(snoop->app);
102
105}
#define ast_free(a)
Definition: astmm.h:180
int ast_audiohook_destroy(struct ast_audiohook *audiohook)
Destroys an audiohook structure.
Definition: audiohook.c:124
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
union ast_frame::@226 data
Structure which contains all of the snoop information.
struct ast_str * app
Stasis application and arguments.
unsigned int spy_active
Whether the spy capability is active or not.
struct ast_audiohook spy
Audiohook used to spy on the channel.
struct ast_audiohook whisper
Audiohook used to whisper on the channel.
struct ast_timer * timer
Timer used for waking up Stasis thread.
struct ast_frame silence
A frame of silence to use when the audiohook returns null.
unsigned int whisper_active
Whether the whisper capability is active or not.
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
Definition: timing.c:154

References stasis_app_snoop::app, ast_audiohook_destroy(), ast_channel_cleanup, ast_free, ast_timer_close(), stasis_app_snoop::chan, ast_frame::data, NULL, ast_frame::ptr, stasis_app_snoop::silence, stasis_app_snoop::spy, stasis_app_snoop::spy_active, stasis_app_snoop::spyee_chan, stasis_app_snoop::timer, stasis_app_snoop::whisper, and stasis_app_snoop::whisper_active.

Referenced by stasis_app_control_snoop().

◆ snoop_determine_format()

static void snoop_determine_format ( struct ast_channel chan,
struct stasis_app_snoop snoop 
)
static

Helper function which gets the format for a Snoop channel based on the channel being snooped on.

Definition at line 294 of file res_stasis_snoop.c.

295{
299
301}
ast_mutex_t lock
Definition: app_sla.c:331
struct ast_format * ast_channel_rawreadformat(struct ast_channel *chan)
struct ast_format * ast_channel_rawwriteformat(struct ast_channel *chan)
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
struct ast_format * ast_format_cache_get_slin_by_rate(unsigned int rate)
Retrieve the best signed linear format given a sample rate.
Definition: format_cache.c:512
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:619
struct ast_format * spy_format
Format in use by the spy audiohook.
#define MAX(a, b)
Definition: utils.h:233

References ast_channel_rawreadformat(), ast_channel_rawwriteformat(), ast_format_cache_get_slin_by_rate(), ast_format_get_sample_rate(), lock, MAX, SCOPED_CHANNELLOCK, and stasis_app_snoop::spy_format.

Referenced by stasis_app_control_snoop().

◆ snoop_fixup()

static int snoop_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
)
static

Definition at line 229 of file res_stasis_snoop.c.

230{
231 struct stasis_app_snoop *snoop = ast_channel_tech_pvt(oldchan);
232
233 if (snoop->chan != oldchan) {
234 return -1;
235 }
236
237 ast_channel_unref(snoop->chan);
238 ast_channel_ref(newchan);
239 snoop->chan = newchan;
240
241 return 0;
242}
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958

References ast_channel_ref, ast_channel_tech_pvt(), ast_channel_unref, and stasis_app_snoop::chan.

◆ snoop_hangup()

static int snoop_hangup ( struct ast_channel chan)
static

Callback function for hanging up a Snoop channel.

Definition at line 204 of file res_stasis_snoop.c.

205{
207
208 if (snoop->spy_active) {
209 ast_audiohook_lock(&snoop->spy);
210 ast_audiohook_detach(&snoop->spy);
211 ast_audiohook_unlock(&snoop->spy);
212 }
213
214 if (snoop->whisper_active) {
218 }
219
220 publish_chanspy_message(snoop, 0);
221
222 ao2_cleanup(snoop);
223
225
226 return 0;
227}
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:313
int ast_audiohook_detach(struct ast_audiohook *audiohook)
Detach audiohook from channel.
Definition: audiohook.c:550
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:318
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
static void publish_chanspy_message(struct stasis_app_snoop *snoop, int start)

References ao2_cleanup, ast_audiohook_detach(), ast_audiohook_lock, ast_audiohook_unlock, ast_channel_tech_pvt(), ast_channel_tech_pvt_set(), stasis_app_snoop::chan, NULL, publish_chanspy_message(), stasis_app_snoop::spy, stasis_app_snoop::spy_active, stasis_app_snoop::whisper, and stasis_app_snoop::whisper_active.

◆ snoop_read()

static struct ast_frame * snoop_read ( struct ast_channel chan)
static

Callback function for reading from a Snoop channel.

Definition at line 177 of file res_stasis_snoop.c.

178{
180 struct ast_frame *frame = NULL;
181
182 /* If we fail to ack the timer OR if any active audiohooks are done hangup */
183 if ((ast_timer_ack(snoop->timer, 1) < 0) ||
184 (snoop->spy_active && snoop->spy.status != AST_AUDIOHOOK_STATUS_RUNNING) ||
186 return NULL;
187 }
188
189 /* Only get audio from the spy audiohook if it is active */
190 if (!snoop->spy_active) {
191 return &ast_null_frame;
192 }
193
194 ast_audiohook_lock(&snoop->spy);
195
196 frame = ast_audiohook_read_frame(&snoop->spy, snoop->spy_samples, snoop->spy_direction, snoop->spy_format);
197
198 ast_audiohook_unlock(&snoop->spy);
199
200 return frame ? frame : &snoop->silence;
201}
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.
Definition: audiohook.c:446
@ AST_AUDIOHOOK_STATUS_RUNNING
Definition: audiohook.h:43
struct ast_frame ast_null_frame
Definition: main/frame.c:79
enum ast_audiohook_status status
Definition: audiohook.h:108
Data structure associated with a single frame of data.
unsigned int spy_samples
Number of samples to be read in when spying.
enum ast_audiohook_direction spy_direction
Direction for spying.
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
Definition: timing.c:171

References ast_audiohook_lock, ast_audiohook_read_frame(), AST_AUDIOHOOK_STATUS_RUNNING, ast_audiohook_unlock, ast_channel_tech_pvt(), ast_null_frame, ast_timer_ack(), stasis_app_snoop::chan, NULL, stasis_app_snoop::silence, stasis_app_snoop::spy, stasis_app_snoop::spy_active, stasis_app_snoop::spy_direction, stasis_app_snoop::spy_format, stasis_app_snoop::spy_samples, ast_audiohook::status, stasis_app_snoop::timer, stasis_app_snoop::whisper, and stasis_app_snoop::whisper_active.

◆ snoop_setup_audiohook()

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 
)
static

Internal helper function which sets up and attaches a snoop audiohook.

Definition at line 267 of file res_stasis_snoop.c.

269{
270 ast_audiohook_init(audiohook, type, "Snoop", 0);
271
272 if (requested_direction == STASIS_SNOOP_DIRECTION_OUT) {
274 } else if (requested_direction == STASIS_SNOOP_DIRECTION_IN) {
276 } else if (requested_direction == STASIS_SNOOP_DIRECTION_BOTH) {
278 } else {
279 return -1;
280 }
281
282 /* Set the audiohook direction so we don't write unnecessary frames */
284 /* If we are unable to set direction, the audiohook either failed to init
285 or someone else started using it already. If we don't bail here, we risk
286 feeding frames that will never be read */
287 return -1;
288 }
289
290 return ast_audiohook_attach(chan, audiohook);
291}
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.
Definition: audiohook.c:100
@ AST_AUDIOHOOK_DIRECTION_READ
Definition: audiohook.h:49
@ AST_AUDIOHOOK_DIRECTION_WRITE
Definition: audiohook.h:50
@ AST_AUDIOHOOK_DIRECTION_BOTH
Definition: audiohook.h:51
int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
Attach audiohook to channel.
Definition: audiohook.c:484
int ast_audiohook_set_frame_feed_direction(struct ast_audiohook *audiohook, enum ast_audiohook_direction direction)
Sets direction on audiohook.
Definition: audiohook.c:150
direction
@ STASIS_SNOOP_DIRECTION_IN
Audio stream in from the channel.
@ STASIS_SNOOP_DIRECTION_OUT
Audio stream out to the channel.
@ STASIS_SNOOP_DIRECTION_BOTH
Audio stream to AND from the channel.

References ast_audiohook_attach(), AST_AUDIOHOOK_DIRECTION_BOTH, AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_init(), ast_audiohook_set_frame_feed_direction(), STASIS_SNOOP_DIRECTION_BOTH, STASIS_SNOOP_DIRECTION_IN, STASIS_SNOOP_DIRECTION_OUT, and type.

Referenced by stasis_app_control_snoop().

◆ snoop_stasis_thread()

static void * snoop_stasis_thread ( void *  obj)
static

Thread used for running the Stasis application.

Definition at line 255 of file res_stasis_snoop.c.

256{
257 RAII_VAR(struct stasis_app_snoop *, snoop, obj, ao2_cleanup);
258
259 ast_pbx_exec_application(snoop->chan, "Stasis", ast_str_buffer(snoop->app));
260
261 ast_hangup(snoop->chan);
262
263 return NULL;
264}
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
int ast_pbx_exec_application(struct ast_channel *chan, const char *app_name, const char *app_args)
Execute an application.
Definition: pbx_app.c:501
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761

References ao2_cleanup, ast_hangup(), ast_pbx_exec_application(), ast_str_buffer(), NULL, and RAII_VAR.

Referenced by stasis_app_control_snoop().

◆ snoop_write()

static int snoop_write ( struct ast_channel chan,
struct ast_frame frame 
)
static

Callback function for writing to a Snoop whisper audiohook.

Definition at line 156 of file res_stasis_snoop.c.

157{
159
160 if (!snoop->whisper_active) {
161 return 0;
162 }
163
168 } else {
170 }
172
173 return 0;
174}
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.
Definition: audiohook.c:167
enum ast_audiohook_direction whisper_direction
Direction for whispering.

References AST_AUDIOHOOK_DIRECTION_BOTH, AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_lock, ast_audiohook_unlock, ast_audiohook_write_frame(), ast_channel_tech_pvt(), stasis_app_snoop::chan, stasis_app_snoop::whisper, stasis_app_snoop::whisper_active, and stasis_app_snoop::whisper_direction.

◆ 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_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
#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)
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
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)
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
@ AST_STATE_UP
Definition: channelstate.h:42
@ 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 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...
@ STASIS_SNOOP_DIRECTION_NONE
No direction.
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
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 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().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 435 of file res_stasis_snoop.c.

436{
437 return 0;
438}

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Stasis application snoop support" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .requires = "res_stasis", }
static

Definition at line 445 of file res_stasis_snoop.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 445 of file res_stasis_snoop.c.

◆ chan_idx

unsigned int chan_idx
static

Index used to keep Snoop channel names unique.

Definition at line 47 of file res_stasis_snoop.c.

Referenced by stasis_app_control_snoop().

◆ snoop_tech

struct ast_channel_tech snoop_tech
static

Channel interface declaration.

Definition at line 245 of file res_stasis_snoop.c.

Referenced by stasis_app_control_snoop().