Asterisk - The Open Source Telephony Project GIT-master-55f4e6d
Data Structures | Macros | Typedefs | Enumerations | Functions
framehook.h File Reference

FrameHook Architecture. More...

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

Go to the source code of this file.

Data Structures

struct  ast_framehook_interface
 

Macros

#define AST_FRAMEHOOK_INTERFACE_VERSION   4
 

Typedefs

typedef void(* ast_framehook_chan_fixup_callback) (void *data, int framehook_id, struct ast_channel *old_chan, struct ast_channel *new_chan)
 This callback is called when a masquerade occurs on a channel with a framehook. More...
 
typedef int(* ast_framehook_consume_callback) (void *data, enum ast_frame_type type)
 This callback is called to determine if the framehook is currently consuming frames of a given type. More...
 
typedef void(* ast_framehook_destroy_callback) (void *data)
 This callback is called immediately before the framehook is destroyed. More...
 
typedef struct ast_frame *(* ast_framehook_event_callback) (struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
 This callback is called every time an event occurs on the framehook. More...
 

Enumerations

enum  ast_framehook_event { AST_FRAMEHOOK_EVENT_READ , AST_FRAMEHOOK_EVENT_WRITE , AST_FRAMEHOOK_EVENT_ATTACHED , AST_FRAMEHOOK_EVENT_DETACHED }
 These are the types of events that the framehook's event callback can receive. More...
 

Functions

int ast_framehook_attach (struct ast_channel *chan, struct ast_framehook_interface *i)
 Attach an framehook onto a channel for frame interception. More...
 
int ast_framehook_detach (struct ast_channel *chan, int framehook_id)
 Detach an framehook from a channel. More...
 
int ast_framehook_list_contains_no_active (struct ast_framehook_list *framehooks)
 Determine if a framehook list is free of active framehooks or not. More...
 
int ast_framehook_list_contains_no_active_of_type (struct ast_framehook_list *framehooks, enum ast_frame_type type)
 Determine if a framehook list is free of active framehooks consuming a specific type of frame. More...
 
int ast_framehook_list_destroy (struct ast_channel *chan)
 This is used by the channel API to detach and destroy all framehooks on a channel during channel destruction. More...
 
void ast_framehook_list_fixup (struct ast_channel *old_chan, struct ast_channel *new_chan)
 This is used by the channel API during a masquerade operation to move all mobile framehooks from the original channel to the clone channel. More...
 
int ast_framehook_list_is_empty (struct ast_framehook_list *framehooks)
 Determine if an framehook list is empty or not. More...
 
struct ast_frameast_framehook_list_read_event (struct ast_framehook_list *framehooks, struct ast_frame *frame)
 This is used by the channel API push a frame read event to a channel's framehook list. More...
 
struct ast_frameast_framehook_list_write_event (struct ast_framehook_list *framehooks, struct ast_frame *frame)
 This is used by the channel API push a frame write event to a channel's framehook list. More...
 

Detailed Description

FrameHook Architecture.

Definition in file framehook.h.

Macro Definition Documentation

◆ AST_FRAMEHOOK_INTERFACE_VERSION

#define AST_FRAMEHOOK_INTERFACE_VERSION   4

Definition at line 227 of file framehook.h.

Typedef Documentation

◆ ast_framehook_chan_fixup_callback

typedef void(* ast_framehook_chan_fixup_callback) (void *data, int framehook_id, struct ast_channel *old_chan, struct ast_channel *new_chan)

This callback is called when a masquerade occurs on a channel with a framehook.

Since
12
Parameters
dataThe data pointer provided at framehook initialization.
framehook_idThe framehook ID where the framehook lives now
old_chanThe channel that was masqueraded.
new_chanThe channel that the masqueraded channel became.

Definition at line 224 of file framehook.h.

◆ ast_framehook_consume_callback

typedef int(* ast_framehook_consume_callback) (void *data, enum ast_frame_type type)

This callback is called to determine if the framehook is currently consuming frames of a given type.

Since
12
Parameters
dataThe data pointer provided at framehook initialization.
typeThe type of frame.
Returns
0 if frame type is being ignored
1 if frame type is not being ignored

Definition at line 213 of file framehook.h.

◆ ast_framehook_destroy_callback

typedef void(* ast_framehook_destroy_callback) (void *data)

This callback is called immediately before the framehook is destroyed.

Since
1.8
Note
This function should be used to clean up any pointers pointing to the framehook structure as the framehook will be freed immediately afterwards.
Parameters
dataThe data pointer provided at framehook initialization. This is a good place to clean up any state data allocated for the framehook stored in this pointer.

Definition at line 200 of file framehook.h.

◆ ast_framehook_event_callback

typedef struct ast_frame *(* ast_framehook_event_callback) (struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)

This callback is called every time an event occurs on the framehook.

Since
1.8

Two events are guaranteed to occur once the ast_framehook_attach() function is called. These events are AST_FRAMEHOOK_EVENT_ATTACHED, which occurs immediately after the framehook is attached to a channel, and AST_FRAMEHOOK_EVENT_DETACHED, which occurs right after the framehook is detached.

It is completely valid for the frame variable to be set to NULL. Always do a NULL check on the frame before attempted to access it. When the frame variable is present, it is safe to view and manipulate that frame in any way possible. It is even safe to return a completely different frame, but when that occurs this function is in charge of freeing the previous frame.

The ast_channel will always be locked during this callback. Never attempt to unlock the channel for any reason.

Parameters
chanThe ast_channel this framehook is attached to
frameThe ast_frame being intercepted for viewing and manipulation
eventThe type of event which is occurring
dataThe data pointer provided at framehook initialization.
Returns
the resulting frame.

Definition at line 1 of file framehook.h.

Enumeration Type Documentation

◆ ast_framehook_event

These are the types of events that the framehook's event callback can receive.

Since
1.8
Enumerator
AST_FRAMEHOOK_EVENT_READ 

frame is intercepted in the read direction on the channel.

AST_FRAMEHOOK_EVENT_WRITE 

frame is intercepted on the write direction on the channel.

AST_FRAMEHOOK_EVENT_ATTACHED 

framehook is attached and running on the channel, the first message sent to event_cb.

AST_FRAMEHOOK_EVENT_DETACHED 

framehook is detached from the channel, last message sent to event_cb.

Definition at line 151 of file framehook.h.

151 {
152 AST_FRAMEHOOK_EVENT_READ, /*!< frame is intercepted in the read direction on the channel. */
153 AST_FRAMEHOOK_EVENT_WRITE, /*!< frame is intercepted on the write direction on the channel. */
154 AST_FRAMEHOOK_EVENT_ATTACHED, /*!< framehook is attached and running on the channel, the first message sent to event_cb. */
155 AST_FRAMEHOOK_EVENT_DETACHED /*!< framehook is detached from the channel, last message sent to event_cb. */
156};
@ AST_FRAMEHOOK_EVENT_ATTACHED
Definition: framehook.h:154
@ AST_FRAMEHOOK_EVENT_DETACHED
Definition: framehook.h:155
@ AST_FRAMEHOOK_EVENT_WRITE
Definition: framehook.h:153
@ AST_FRAMEHOOK_EVENT_READ
Definition: framehook.h:152

Function Documentation

◆ ast_framehook_attach()

int ast_framehook_attach ( struct ast_channel chan,
struct ast_framehook_interface i 
)

Attach an framehook onto a channel for frame interception.

Since
1.8
Parameters
chanast_channel The channel to attach the hook on to.
iframehook interface, The framehook's callback functions and stored data.
Precondition
The Channel must be locked during this function call.
Note
The data pointer is never touched by the framehook API except to provide it during the event and destruction callbacks. It is entirely up to the application using this API to manage the memory associated with the data pointer.
Return values
non-negativesuccess, id representing this hook on the channel
-1failure

Definition at line 132 of file framehook.c.

133{
134 struct ast_framehook *framehook;
135 struct ast_framehook_list *fh_list;
136 struct ast_frame *frame;
138 ast_log(LOG_ERROR, "Version '%hu' of framehook interface not what we compiled against (%i)\n",
140 return -1;
141 }
142 if (!i->event_cb || !(framehook = ast_calloc(1, sizeof(*framehook)))) {
143 return -1;
144 }
145 framehook->i = *i;
146 framehook->chan = chan;
147
148 /* create the framehook list if it didn't already exist */
149 if (!ast_channel_framehooks(chan)) {
150 if (!(fh_list = ast_calloc(1, sizeof(*ast_channel_framehooks(chan))))) {
151 ast_free(framehook);
152 return -1;
153 }
154 ast_channel_framehooks_set(chan, fh_list);
155 }
156
158 framehook->id = ++ast_channel_framehooks(chan)->id_count;
159 AST_LIST_INSERT_TAIL(&ast_channel_framehooks(chan)->list, framehook, list);
160
161 /* Tell the event callback we're live and rocking */
162 frame = framehook->i.event_cb(framehook->chan, NULL, AST_FRAMEHOOK_EVENT_ATTACHED, framehook->i.data);
163
164 /* Never assume anything about this function. If you can return a frame during
165 * the attached event, then assume someone will. */
166 if (frame) {
167 ast_frfree(frame);
168 }
169
170 if (ast_channel_is_bridged(chan)) {
172 }
173
174 return framehook->id;
175}
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
Variant of ast_channel_set_unbridged. Use this if the channel is already locked prior to calling.
void ast_channel_framehooks_set(struct ast_channel *chan, struct ast_framehook_list *value)
struct ast_framehook_list * ast_channel_framehooks(const struct ast_channel *chan)
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10545
#define AST_FRAMEHOOK_INTERFACE_VERSION
Definition: framehook.h:227
#define ast_frfree(fr)
#define LOG_ERROR
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define NULL
Definition: resample.c:96
Data structure associated with a single frame of data.
ast_framehook_event_callback event_cb
Definition: framehook.h:233
unsigned int count
Definition: framehook.c:51
unsigned int id_count
Definition: framehook.c:53
struct ast_framehook_interface i
Definition: framehook.c:38
struct ast_channel * chan
Definition: framehook.c:40
unsigned int id
Definition: framehook.c:42

References ast_calloc, ast_channel_framehooks(), ast_channel_framehooks_set(), ast_channel_is_bridged(), ast_channel_set_unbridged_nolock(), AST_FRAMEHOOK_EVENT_ATTACHED, AST_FRAMEHOOK_INTERFACE_VERSION, ast_free, ast_frfree, AST_LIST_INSERT_TAIL, ast_log, ast_framehook::chan, ast_framehook_list::count, ast_framehook_interface::data, ast_framehook_interface::event_cb, ast_framehook::i, ast_framehook::id, ast_framehook_list::id_count, LOG_ERROR, NULL, and ast_framehook_interface::version.

Referenced by aoc_attach_framehook(), ast_channel_suppress(), ast_framehook_list_fixup(), ast_jb_create_framehook(), attach_framehook(), dtmfstore_exec(), fax_detect_attach(), fax_gateway_attach(), frame_drop_helper(), frame_trace_helper(), handle_remb_set(), native_rtp_bridge_framehook_attach(), refer_blind_callback(), set_hold_intercept(), and t38_attach_framehook().

◆ ast_framehook_detach()

int ast_framehook_detach ( struct ast_channel chan,
int  framehook_id 
)

Detach an framehook from a channel.

Since
1.8
Precondition
The Channel must be locked during this function call. If this function is never called after attaching an framehook, the framehook will be detached and destroyed during channel destruction.
Parameters
chanThe channel the framehook is attached to
framehook_idThe framehook's id
Return values
0success
-1framehook did not exist on the channel. This means the framehook either never existed on the channel, or was already detached.

Definition at line 177 of file framehook.c.

178{
179 struct ast_framehook *framehook;
180 int res = -1;
181
183 return res;
184 }
185
187 if (framehook->id == id) {
188 /* we mark for detachment rather than doing explicitly here because
189 * it needs to be safe for this function to be called within the
190 * event callback. If we allowed the hook to actually be destroyed
191 * immediately here, the event callback would crash on exit. */
192 framehook->detach_and_destroy_me = 1;
193 res = 0;
194 break;
195 }
196 }
198
199 if (!res && ast_channel_is_bridged(chan)) {
201 }
202
203 return res;
204}
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
struct ast_framehook::@357 list
int detach_and_destroy_me
Definition: framehook.c:44

References ast_channel_framehooks(), ast_channel_is_bridged(), ast_channel_set_unbridged_nolock(), AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_framehook::chan, ast_framehook::detach_and_destroy_me, ast_framehook::id, and ast_framehook::list.

Referenced by acf_faxopt_write(), ast_channel_suppress(), ast_channel_unsuppress(), ast_framehook_list_fixup(), ast_jb_create_framehook(), fax_detect_framehook(), fax_gateway_detect_t38(), fax_gateway_framehook(), fax_gateway_request_t38(), fixup_callback(), frame_drop_helper(), frame_trace_helper(), handle_remb_set(), native_rtp_bridge_framehook_detach(), refer_blind_callback(), refer_progress_bridge(), refer_progress_framehook(), remove_dtmf_store(), remove_framehook(), remove_hold_intercept(), t38_attach_framehook(), t38_masq(), and transfer_target_framehook_cb().

◆ ast_framehook_list_contains_no_active()

int ast_framehook_list_contains_no_active ( struct ast_framehook_list framehooks)

Determine if a framehook list is free of active framehooks or not.

Since
12.0.0
Precondition
The channel must be locked during this function call.
Parameters
framehooksthe framehook list
Return values
0not empty
1is empty (aside from dying framehooks)
Note
This function is very similar to ast_framehook_list_is_empty, but it checks individual framehooks to see if they have been marked for destruction and doesn't count them if they are.

Definition at line 282 of file framehook.c.

283{
285}
int ast_framehook_list_contains_no_active_of_type(struct ast_framehook_list *framehooks, enum ast_frame_type type)
Determine if a framehook list is free of active framehooks consuming a specific type of frame.
Definition: framehook.c:287

References ast_framehook_list_contains_no_active_of_type().

Referenced by ast_channel_has_audio_frame_or_monitor().

◆ ast_framehook_list_contains_no_active_of_type()

int ast_framehook_list_contains_no_active_of_type ( struct ast_framehook_list framehooks,
enum ast_frame_type  type 
)

Determine if a framehook list is free of active framehooks consuming a specific type of frame.

Since
12.3.0
Precondition
The channel must be locked during this function call.
Parameters
framehooksthe framehook list
typetype of frame
Return values
0not empty
1is empty (aside from dying framehooks)
Note
This function is very similar to ast_framehook_list_is_empty, but it checks individual framehooks to see if they have been marked for destruction and doesn't count them if they are.

Definition at line 287 of file framehook.c.

289{
290 struct ast_framehook *cur;
291
292 if (!framehooks) {
293 return 1;
294 }
295
296 if (AST_LIST_EMPTY(&framehooks->list)) {
297 return 1;
298 }
299
300 AST_LIST_TRAVERSE(&framehooks->list, cur, list) {
301 if (cur->detach_and_destroy_me) {
302 continue;
303 }
304 if (type && cur->i.consume_cb && !cur->i.consume_cb(cur->i.data, type)) {
305 continue;
306 }
307 return 0;
308 }
309
310 return 1;
311}
static const char type[]
Definition: chan_ooh323.c:109
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
ast_framehook_consume_callback consume_cb
Definition: framehook.h:240
struct ast_framehook_list::@358 list

References AST_LIST_EMPTY, AST_LIST_TRAVERSE, ast_framehook_interface::consume_cb, ast_framehook_interface::data, ast_framehook::detach_and_destroy_me, ast_framehook::i, ast_framehook::list, ast_framehook_list::list, and type.

Referenced by ast_channel_has_hook_requiring_audio(), and ast_framehook_list_contains_no_active().

◆ ast_framehook_list_destroy()

int ast_framehook_list_destroy ( struct ast_channel chan)

This is used by the channel API to detach and destroy all framehooks on a channel during channel destruction.

Since
1.8
Precondition
The Channel must be locked during this function call.
Parameters
chanchannel containing the framehook list to destroy.
Return values
0success
-1failure

Definition at line 206 of file framehook.c.

207{
208 struct ast_framehook *framehook;
209
211 return 0;
212 }
216 }
220 return 0;
221}
static void framehook_detach(struct ast_framehook *framehook, enum framehook_detachment_mode mode)
Definition: framehook.c:66
@ FRAMEHOOK_DETACH_DESTROY
Definition: framehook.c:60
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557

References ast_channel_framehooks(), ast_channel_framehooks_set(), ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_framehook::chan, framehook_detach(), FRAMEHOOK_DETACH_DESTROY, ast_framehook::list, and NULL.

Referenced by destroy_hooks().

◆ ast_framehook_list_fixup()

void ast_framehook_list_fixup ( struct ast_channel old_chan,
struct ast_channel new_chan 
)

This is used by the channel API during a masquerade operation to move all mobile framehooks from the original channel to the clone channel.

Since
12.5.0
Precondition
Both channels must be locked prior to this function call.
Parameters
old_chanThe channel being cloned from
new_chanThe channel being cloned to

Definition at line 223 of file framehook.c.

224{
225 struct ast_framehook *framehook;
226 int moved_framehook_id;
227
228 if (ast_channel_framehooks(new_chan)) {
230 if (framehook->i.disable_inheritance) {
231 ast_framehook_detach(new_chan, framehook->id);
232 continue;
233 }
234
235 if (framehook->i.chan_breakdown_cb) {
236 framehook->i.chan_breakdown_cb(framehook->i.data, framehook->id,
237 old_chan, new_chan);
238 }
239 }
241 }
242
243 if (!ast_channel_framehooks(old_chan)) {
244 return;
245 }
246
248 && ast_channel_is_bridged(old_chan)) {
250 }
251 while ((framehook = AST_LIST_REMOVE_HEAD(&ast_channel_framehooks(old_chan)->list, list))) {
252 /* If inheritance is not allowed for this framehook, just destroy it. */
253 if (framehook->i.disable_inheritance) {
255 continue;
256 }
257
258 /* Otherwise move it to the other channel and perform any fixups set by the framehook interface */
259 moved_framehook_id = ast_framehook_attach(new_chan, &framehook->i);
260 if (moved_framehook_id < 0) {
261 ast_log(LOG_WARNING, "Failed framehook copy during masquerade. Expect loss of features.\n");
263 } else {
264 if (framehook->i.chan_fixup_cb) {
265 framehook->i.chan_fixup_cb(framehook->i.data, moved_framehook_id,
266 old_chan, new_chan);
267 }
268
270 }
271 }
272}
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
Definition: framehook.c:132
int ast_framehook_detach(struct ast_channel *chan, int id)
Detach an framehook from a channel.
Definition: framehook.c:177
@ FRAMEHOOK_DETACH_PRESERVE
Definition: framehook.c:63
#define LOG_WARNING
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
ast_framehook_chan_fixup_callback chan_fixup_cb
Definition: framehook.h:244
ast_framehook_chan_fixup_callback chan_breakdown_cb
Definition: framehook.h:248

References ast_channel_framehooks(), ast_channel_is_bridged(), ast_channel_set_unbridged_nolock(), ast_framehook_attach(), ast_framehook_detach(), AST_LIST_EMPTY, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log, ast_framehook_interface::chan_breakdown_cb, ast_framehook_interface::chan_fixup_cb, ast_framehook_interface::data, ast_framehook_interface::disable_inheritance, framehook_detach(), FRAMEHOOK_DETACH_DESTROY, FRAMEHOOK_DETACH_PRESERVE, ast_framehook::i, ast_framehook::id, ast_framehook::list, and LOG_WARNING.

Referenced by channel_do_masquerade().

◆ ast_framehook_list_is_empty()

int ast_framehook_list_is_empty ( struct ast_framehook_list framehooks)

Determine if an framehook list is empty or not.

Since
1.8
Precondition
The Channel must be locked during this function call.
Parameters
framehooksthe framehook list
Return values
0not empty
1is empty

Definition at line 274 of file framehook.c.

275{
276 if (!framehooks) {
277 return 1;
278 }
279 return AST_LIST_EMPTY(&framehooks->list) ? 1 : 0;
280}

References AST_LIST_EMPTY, and ast_framehook_list::list.

Referenced by ast_indicate_data().

◆ ast_framehook_list_read_event()

struct ast_frame * ast_framehook_list_read_event ( struct ast_framehook_list framehooks,
struct ast_frame frame 
)

This is used by the channel API push a frame read event to a channel's framehook list.

Since
1.8

After this function completes, the resulting frame that is returned could be anything, even NULL. There is nothing to keep up with after this function. If the frame is modified, the framehook callback is in charge of any memory management associated with that modification.

Precondition
The Channel must be locked during this function call.
Parameters
framehookslist to push event to.
framebeing pushed to the framehook list.
Returns
The resulting frame after being viewed and modified by the framehook callbacks.

Definition at line 318 of file framehook.c.

319{
320 return framehook_list_push_event(framehooks, frame, AST_FRAMEHOOK_EVENT_READ);
321}
static struct ast_frame * framehook_list_push_event(struct ast_framehook_list *framehooks, struct ast_frame *frame, enum ast_framehook_event event)
Definition: framehook.c:83

References AST_FRAMEHOOK_EVENT_READ, and framehook_list_push_event().

Referenced by __ast_read().

◆ ast_framehook_list_write_event()

struct ast_frame * ast_framehook_list_write_event ( struct ast_framehook_list framehooks,
struct ast_frame frame 
)

This is used by the channel API push a frame write event to a channel's framehook list.

Since
1.8

After this function completes, the resulting frame that is returned could be anything, even NULL. There is nothing to keep up with after this function. If the frame is modified, the framehook callback is in charge of any memory management associated with that modification.

Precondition
The Channel must be locked during this function call.
Parameters
framehookslist to push event to.
framebeing pushed to the framehook list.
Returns
The resulting frame after being viewed and modified by the framehook callbacks.

Definition at line 313 of file framehook.c.

314{
315 return framehook_list_push_event(framehooks, frame, AST_FRAMEHOOK_EVENT_WRITE);
316}

References AST_FRAMEHOOK_EVENT_WRITE, and framehook_list_push_event().

Referenced by ast_indicate_data(), and ast_write_stream().