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

Defines

#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.
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.
typedef void(* ast_framehook_destroy_callback )(void *data)
 This callback is called immediately before the framehook is destroyed.
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.

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.
int ast_framehook_detach (struct ast_channel *chan, int framehook_id)
 Detach an framehook from a channel.
int ast_framehook_list_contains_no_active (struct ast_framehook_list *framehooks)
 Determine if a framehook list is free of active framehooks or not.
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.
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.
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.
int ast_framehook_list_is_empty (struct ast_framehook_list *framehooks)
 Determine if an framehook list is empty or not.
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.
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.


Detailed Description

FrameHook Architecture.

Definition in file framehook.h.


Define Documentation

#define AST_FRAMEHOOK_INTERFACE_VERSION   4


Typedef Documentation

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:
data,The data pointer provided at framehook initialization.
framehook_id,The framehook ID where the framehook lives now
old_chan,The channel that was masqueraded.
new_chan,The channel that the masqueraded channel became.

Definition at line 224 of file framehook.h.

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:
data,The data pointer provided at framehook initilization.
type,The 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.

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:
data,The 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.

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:
channel,The ast_channel this framehook is attached to
frame,The ast_frame being intercepted for viewing and manipulation
event,The type of event which is occurring
data,The data pointer provided at framehook initilization.
Return values:
the resulting frame.

Definition at line 184 of file framehook.h.


Enumeration Type Documentation

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.

00151                          {
00152    AST_FRAMEHOOK_EVENT_READ, /*!< frame is intercepted in the read direction on the channel. */
00153    AST_FRAMEHOOK_EVENT_WRITE, /*!< frame is intercepted on the write direction on the channel. */
00154    AST_FRAMEHOOK_EVENT_ATTACHED, /*!< framehook is attached and running on the channel, the first message sent to event_cb. */
00155    AST_FRAMEHOOK_EVENT_DETACHED /*!< framehook is detached from the channel, last message sent to event_cb. */
00156 };


Function Documentation

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:
chan ast_channel The channel to attach the hook on to.
i framehook 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:
On success, non-negative id representing this hook on the channel
On failure, -1

Definition at line 134 of file framehook.c.

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 ast_channel_suppress(), ast_framehook_list_fixup(), ast_jb_create_framehook(), attach_framehook(), fax_detect_attach(), fax_gateway_attach(), frame_trace_helper(), native_rtp_bridge_framehook_attach(), refer_blind_callback(), and t38_attach_framehook().

00135 {
00136    struct ast_framehook *framehook;
00137    struct ast_framehook_list *fh_list;
00138    struct ast_frame *frame;
00139    if (i->version != AST_FRAMEHOOK_INTERFACE_VERSION) {
00140       ast_log(LOG_ERROR, "Version '%hu' of framehook interface not what we compiled against (%i)\n",
00141          i->version, AST_FRAMEHOOK_INTERFACE_VERSION);
00142       return -1;
00143    }
00144    if (!i->event_cb || !(framehook = ast_calloc(1, sizeof(*framehook)))) {
00145       return -1;
00146    }
00147    framehook->i = *i;
00148    framehook->chan = chan;
00149 
00150    /* create the framehook list if it didn't already exist */
00151    if (!ast_channel_framehooks(chan)) {
00152       if (!(fh_list = ast_calloc(1, sizeof(*ast_channel_framehooks(chan))))) {
00153          ast_free(framehook);
00154          return -1;
00155       }
00156       ast_channel_framehooks_set(chan, fh_list);
00157    }
00158 
00159    ast_channel_framehooks(chan)->count++;
00160    framehook->id = ++ast_channel_framehooks(chan)->id_count;
00161    AST_LIST_INSERT_TAIL(&ast_channel_framehooks(chan)->list, framehook, list);
00162 
00163    /* Tell the event callback we're live and rocking */
00164    frame = framehook->i.event_cb(framehook->chan, NULL, AST_FRAMEHOOK_EVENT_ATTACHED, framehook->i.data);
00165 
00166    /* Never assume anything about this function. If you can return a frame during
00167     * the attached event, then assume someone will. */
00168    if (frame) {
00169       ast_frfree(frame);
00170    }
00171 
00172    if (ast_channel_is_bridged(chan)) {
00173       ast_channel_set_unbridged_nolock(chan, 1);
00174    }
00175 
00176    return framehook->id;
00177 }

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:
chan The channel the framehook is attached to
framehook_id The framehook's id
Return values:
0 success
-1 framehook did not exist on the channel. This means the framehook either never existed on the channel, or was already detached.

Definition at line 179 of file framehook.c.

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::detach_and_destroy_me, and ast_framehook::id.

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_trace_helper(), native_rtp_bridge_framehook_detach(), refer_blind_callback(), refer_progress_bridge(), refer_progress_framehook(), t38_attach_framehook(), t38_masq(), and transfer_target_framehook_cb().

00180 {
00181    struct ast_framehook *framehook;
00182    int res = -1;
00183 
00184    if (!ast_channel_framehooks(chan)) {
00185       return res;
00186    }
00187 
00188    AST_LIST_TRAVERSE_SAFE_BEGIN(&ast_channel_framehooks(chan)->list, framehook, list) {
00189       if (framehook->id == id) {
00190          /* we mark for detachment rather than doing explicitly here because
00191           * it needs to be safe for this function to be called within the
00192           * event callback.  If we allowed the hook to actually be destroyed
00193           * immediately here, the event callback would crash on exit. */
00194          framehook->detach_and_destroy_me = 1;
00195          res = 0;
00196          break;
00197       }
00198    }
00199    AST_LIST_TRAVERSE_SAFE_END;
00200 
00201    if (!res && ast_channel_is_bridged(chan)) {
00202       ast_channel_set_unbridged_nolock(chan, 1);
00203    }
00204 
00205    return res;
00206 }

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:
framehooks the framehook list
Return values:
0,not empty
1,is 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 284 of file framehook.c.

References ast_framehook_list_contains_no_active_of_type().

Referenced by ast_channel_has_audio_frame_or_monitor().

00285 {
00286    return ast_framehook_list_contains_no_active_of_type(framehooks, 0);
00287 }

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:
framehooks the framehook list
Return values:
0,not empty
1,is 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 289 of file framehook.c.

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, and ast_framehook_list::list.

Referenced by ast_channel_has_hook_requiring_audio(), and ast_framehook_list_contains_no_active().

00291 {
00292    struct ast_framehook *cur;
00293 
00294    if (!framehooks) {
00295       return 1;
00296    }
00297 
00298    if (AST_LIST_EMPTY(&framehooks->list)) {
00299       return 1;
00300    }
00301 
00302    AST_LIST_TRAVERSE(&framehooks->list, cur, list) {
00303       if (cur->detach_and_destroy_me) {
00304          continue;
00305       }
00306       if (type && cur->i.consume_cb && !cur->i.consume_cb(cur->i.data, type)) {
00307          continue;
00308       }
00309       return 0;
00310    }
00311 
00312    return 1;
00313 }

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:
chan channel containing the framehook list to destroy.
Return values:
0 success
-1 failure

Definition at line 208 of file framehook.c.

References ast_channel_framehooks(), ast_channel_framehooks_set(), ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, framehook_detach(), FRAMEHOOK_DETACH_DESTROY, and NULL.

Referenced by destroy_hooks().

00209 {
00210    struct ast_framehook *framehook;
00211 
00212    if (!ast_channel_framehooks(chan)) {
00213       return 0;
00214    }
00215    AST_LIST_TRAVERSE_SAFE_BEGIN(&ast_channel_framehooks(chan)->list, framehook, list) {
00216       AST_LIST_REMOVE_CURRENT(list);
00217       framehook_detach(framehook, FRAMEHOOK_DETACH_DESTROY);
00218    }
00219    AST_LIST_TRAVERSE_SAFE_END;
00220    ast_free(ast_channel_framehooks(chan));
00221    ast_channel_framehooks_set(chan, NULL);
00222    return 0;
00223 }

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_chan The channel being cloned from
new_chan The channel being cloned to

Definition at line 225 of file framehook.c.

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, and LOG_WARNING.

Referenced by channel_do_masquerade().

00226 {
00227    struct ast_framehook *framehook;
00228    int moved_framehook_id;
00229 
00230    if (ast_channel_framehooks(new_chan)) {
00231       AST_LIST_TRAVERSE_SAFE_BEGIN(&ast_channel_framehooks(new_chan)->list, framehook, list) {
00232          if (framehook->i.disable_inheritance) {
00233             ast_framehook_detach(new_chan, framehook->id);
00234             continue;
00235          }
00236 
00237          if (framehook->i.chan_breakdown_cb) {
00238             framehook->i.chan_breakdown_cb(framehook->i.data, framehook->id,
00239                old_chan, new_chan);
00240          }
00241       }
00242       AST_LIST_TRAVERSE_SAFE_END;
00243    }
00244 
00245    if (!ast_channel_framehooks(old_chan)) {
00246       return;
00247    }
00248 
00249    if (!AST_LIST_EMPTY(&ast_channel_framehooks(old_chan)->list)
00250       && ast_channel_is_bridged(old_chan)) {
00251       ast_channel_set_unbridged_nolock(old_chan, 1);
00252    }
00253    while ((framehook = AST_LIST_REMOVE_HEAD(&ast_channel_framehooks(old_chan)->list, list))) {
00254       /* If inheritance is not allowed for this framehook, just destroy it. */
00255       if (framehook->i.disable_inheritance) {
00256          framehook_detach(framehook, FRAMEHOOK_DETACH_DESTROY);
00257          continue;
00258       }
00259 
00260       /* Otherwise move it to the other channel and perform any fixups set by the framehook interface */
00261       moved_framehook_id = ast_framehook_attach(new_chan, &framehook->i);
00262       if (moved_framehook_id < 0) {
00263          ast_log(LOG_WARNING, "Failed framehook copy during masquerade. Expect loss of features.\n");
00264          framehook_detach(framehook, FRAMEHOOK_DETACH_DESTROY);
00265       } else {
00266          if (framehook->i.chan_fixup_cb) {
00267             framehook->i.chan_fixup_cb(framehook->i.data, moved_framehook_id,
00268                old_chan, new_chan);
00269          }
00270 
00271          framehook_detach(framehook, FRAMEHOOK_DETACH_PRESERVE);
00272       }
00273    }
00274 }

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:
framehooks the framehook list
Return values:
0,not empty
1,is empty

Definition at line 276 of file framehook.c.

References AST_LIST_EMPTY, and ast_framehook_list::list.

Referenced by ast_indicate_data().

00277 {
00278    if (!framehooks) {
00279       return 1;
00280    }
00281    return AST_LIST_EMPTY(&framehooks->list) ? 1 : 0;
00282 }

struct ast_frame* ast_framehook_list_read_event ( struct ast_framehook_list framehooks,
struct ast_frame frame 
) [read]

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:
framehooks list to push event to.
frame being pushed to the framehook list.
Returns:
The resulting frame after being viewed and modified by the framehook callbacks.

Definition at line 320 of file framehook.c.

References AST_FRAMEHOOK_EVENT_READ, and framehook_list_push_event().

Referenced by __ast_read().

00321 {
00322    return framehook_list_push_event(framehooks, frame, AST_FRAMEHOOK_EVENT_READ);
00323 }

struct ast_frame* ast_framehook_list_write_event ( struct ast_framehook_list framehooks,
struct ast_frame frame 
) [read]

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:
framehooks list to push event to.
frame being pushed to the framehook list.
Returns:
The resulting frame after being viewed and modified by the framehook callbacks.

Definition at line 315 of file framehook.c.

References AST_FRAMEHOOK_EVENT_WRITE, and framehook_list_push_event().

Referenced by ast_indicate_data(), and ast_write().

00316 {
00317    return framehook_list_push_event(framehooks, frame, AST_FRAMEHOOK_EVENT_WRITE);
00318 }


Generated on Thu Apr 16 06:31:10 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6