/usr/include/asterisk/framehook.h is in asterisk-dev 1:1.8.13.1~dfsg1-3+deb7u3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | /*
* Asterisk -- An open source telephony toolkit.
*
* Copyright (C) 2010, Digium, Inc.
*
* David Vossel <dvossel@digium.com>
*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
*/
/*! \file
* \brief FrameHook Architecture
*/
/*!
\page AstFrameHookAPI Asterisk FrameHook API
\section FrameHookFunctionality How FrameHooks Work
FrameHooks work by intercepting all frames being written and read off
a channel and allowing those frames to be viewed and manipulated within a
call back function. Frame interception occurs before any processing is
done on the frame, which means this hook can be used to transparently
manipulate a frame before it is read from the channel or written
to the tech_pvt. This API can be thought of as a layer between the
channel API and the Asterisk core when going in the READ direction, and
as a layer between the Channel API and the tech_pvt when going in the
WRITE direction.
\section FrameHookAPIUsage How to Use an FrameHook
Attaching and detaching an FrameHook to a channel is very simple. There are only
two functions involved, ast_framehook_attach() which will return an id representing
the new FrameHook on the channel, and ast_framehook_detach() which signals the
FrameHook for detachment and destruction. Below is detailed information each of these
functions and their usage.
\code
struct ast_framehook_interface interface = {
.version = AST_FRAMEHOOK_INTERFACE_VERSION,
.event_cb = hook_event_cb,
.destroy_cb = hook_destroy_cb,
.data = data, // where the data ptr points to any custom data used later by the hook cb.
};
int id = ast_framehook_attach(channel, &interface);
\endcode
The ast_framehook_attach() function creates and attaches a new FrameHook onto
a channel. Once attached to the channel, the FrameHook will call the event_callback
function each time a frame is written or read on the channel. A custom data
pointer can be provided to this function to store on the FrameHook as well. This
pointer can be used to keep up with any statefull information associated with the FrameHook
and is provided during the event_callback function. The destroy_callback function is optional.
This function exists so any custom data stored on the FrameHook can be destroyed before
the Framehook if destroyed.
\code
ast_framehook_detach(channel, id);
\endcode
The ast_framehook_detach() function signals the FrameHook represented by an id to
be detached and destroyed on a channel. Since it is possible this function may be called
during the FrameHook's event callback, it is impossible to synchronously detach the
FrameHook from the channel during this function call. It is guaranteed that the next
event proceeding the ast_framehook_detach() will be of type AST_FRAMEHOOK_EVENT_DETACH,
and that after that event occurs no other event will ever be issued for that FrameHook.
Once the FrameHook is destroyed, the destroy callback function will be called if it was
provided. Note that if this function is never called, the FrameHook will be detached
on channel destruction.
\section FrameHookAPICodeExample FrameHook Example Code
The example code below attaches an FrameHook on a channel, and then detachs it when
the first ast_frame is read or written to the event callback function. The Framehook's id
is stored on the FrameHook's data pointer so it can be detached within the callback.
\code
static void destroy_cb(void *data) {
ast_free(data);
}
static struct ast_frame *event_cb(struct ast_channel *chan,
struct ast_frame *frame,
enum ast_framehook_event event,
void *data) {
int *id = data;
if (!frame) {
return frame;
}
if (event == AST_FRAMEHOOK_EVENT_WRITE) {
ast_log(LOG_NOTICE, "YAY we received a frame in the write direction, Type: %d\n", frame->frametype)
ast_framehook_detach(chan, id); // the channel is guaranteed to be locked during this function call.
} else if (event == AST_FRAMEHOOK_EVENT_READ) {
ast_log(LOG_NOTICE, "YAY we received a frame in the read direction: Type: %d\n", frame->frametype);
ast_framehook_detach(chan, id); // the channel is guaranteed to be locked during this function call.
}
return frame;
{
int some_function()
{
struct ast_framehook_interface interface = {
.version = AST_FRAMEHOOK_INTERFACE_VERSION,
.event_cb = hook_event_cb,
.destroy_cb = hook_destroy_cb,
};
int *id = ast_calloc(1, sizeof(int));
if (!id) {
return -1;
}
interface.data = id; // This data will be returned to us in the callbacks.
ast_channel_lock(chan);
*id = ast_framehook_attach(chan, &interface);
ast_channel_unlock(chan);
if (*id < 0) {
// framehook attach failed, free data
ast_free(id);
return -1;
}
return 0;
}
\endcode
*/
#ifndef _AST_FRAMEHOOK_H_
#define _AST_FRAMEHOOK_H_
#include "asterisk/linkedlists.h"
#include "asterisk/frame.h"
struct ast_framehook;
struct ast_framehook_list;
/*!
* \brief These are the types of events that the framehook's event callback can receive
* \since 1.8
*/
enum ast_framehook_event {
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. */
};
/*!
* \brief This callback is called every time an event occurs on the framehook.
* \since 1.8
*
* \details 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.
*
* \param channel, The ast_channel this framehook is attached to
* \param frame, The ast_frame being intercepted for viewing and manipulation
* \param event, The type of event which is occurring
* \param data, The data pointer provided at framehook initilization.
*
* \retval the resulting frame.
*/
typedef struct ast_frame *(*ast_framehook_event_callback)(
struct ast_channel *chan,
struct ast_frame *frame,
enum ast_framehook_event event,
void *data);
/*!
* \brief 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.
*
* \param 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.
*/
typedef void (*ast_framehook_destroy_callback)(void *data);
#define AST_FRAMEHOOK_INTERFACE_VERSION 1
/*! This interface is required for attaching a framehook to a channel. */
struct ast_framehook_interface {
/*! framehook interface version number */
uint16_t version;
/*! event_cb represents the function that will be called everytime an event occurs on the framehook. */
ast_framehook_event_callback event_cb;
/*! destroy_cb is optional. This function is called immediately before the framehook
* is destroyed to allow for stored_data cleanup. */
ast_framehook_destroy_callback destroy_cb;
/*! This pointer can represent any custom data to be stored on the !framehook. This
* data pointer will be provided during each event callback which allows the framehook
* to store any stateful data associated with the application using the hook. */
void *data;
};
/*!
* \brief Attach an framehook onto a channel for frame interception.
* \since 1.8
*
* \param ast_channel, The channel to attach the hook on to.
* \param framehook interface, The framehook's callback functions and stored data.
*
* \pre XXX The Channel must be locked during this function all.
*
* \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.
*
* \retval On success, positive id representing this hook on the channel
* \retval On failure, -1
*/
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i);
/*!
* \brief Detach an framehook from a channel.
* \since 1.8
*
* \pre XXX The Channel must be locked during this function all.
* If this function is never called after attaching an framehook,
* the framehook will be detached and destroyed during channel
* destruction.
*
* \param The channel the framehook is attached to
* \param The framehook's id
*
* \retval 0 success
* \retval -1 framehook did not exist on the channel. This means the
* framehook either never existed on the channel, or was already detached.
*/
int ast_framehook_detach(struct ast_channel *chan, int framehook_id);
/*!
* \brief This is used by the channel API to detach and destroy all
* framehooks on a channel during channel destruction.
* \since 1.8
*
* \pre XXX The Channel must be locked during this function all.
*
* \param channel containing the framehook list to destroy.
* \retval 0 success
* \retval -1 failure
*/
int ast_framehook_list_destroy(struct ast_channel *chan);
/*!
* \brief This is used by the channel API push a frame read event to a channel's framehook list.
* \since 1.8
*
* \details 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.
*
* \pre XXX The Channel must be locked during this function all.
*
* \param framehook list to push event to.
* \param frame being pushed to the framehook list.
*
* \return The resulting frame after being viewed and modified by the framehook callbacks.
*/
struct ast_frame *ast_framehook_list_read_event(struct ast_framehook_list *framehooks, struct ast_frame *frame);
/*!
* \brief This is used by the channel API push a frame write event to a channel's framehook list.
* \since 1.8
*
* \details 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.
*
* \pre XXX The Channel must be locked during this function all.
*
* \param framehook list to push event to.
* \param frame being pushed to the framehook list.
*
* \return The resulting frame after being viewed and modified by the framehook callbacks.
*/
struct ast_frame *ast_framehook_list_write_event(struct ast_framehook_list *framehooks, struct ast_frame *frame);
/*!
* \brief Determine if an framehook list is empty or not
* \since 1.8
* \pre XXX The Channel must be locked during this function all.
*
* \param the framehook list
* \retval 0, not empty
* \retval 1, is empty
*/
int ast_framehook_list_is_empty(struct ast_framehook_list *framehooks);
#endif /* _AST_FRAMEHOOK_H */
|