Asterisk - The Open Source Telephony Project  18.5.0
framehook.h
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2010, Digium, Inc.
5  *
6  * David Vossel <[email protected]>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  * \brief FrameHook Architecture
21  */
22 
23 /*!
24 
25 \page AstFrameHookAPI Asterisk FrameHook API
26 
27 \section FrameHookFunctionality How FrameHooks Work
28  FrameHooks work by intercepting all frames being written and read off
29  a channel and allowing those frames to be viewed and manipulated within a
30  call back function. Frame interception occurs before any processing is
31  done on the frame, which means this hook can be used to transparently
32  manipulate a frame before it is read from the channel or written
33  to the tech_pvt. This API can be thought of as a layer between the
34  channel API and the Asterisk core when going in the READ direction, and
35  as a layer between the Channel API and the tech_pvt when going in the
36  WRITE direction.
37 
38 \section FrameHookAPIUsage How to Use an FrameHook
39  Attaching and detaching an FrameHook to a channel is very simple. There are only
40  two functions involved, ast_framehook_attach() which will return an id representing
41  the new FrameHook on the channel, and ast_framehook_detach() which signals the
42  FrameHook for detachment and destruction. Below is detailed information each of these
43  functions and their usage.
44 
45 \code
46  struct ast_framehook_interface interface = {
47  .version = AST_FRAMEHOOK_INTERFACE_VERSION,
48  .event_cb = hook_event_cb,
49  .destroy_cb = hook_destroy_cb,
50  .data = data, // where the data ptr points to any custom data used later by the hook cb.
51  };
52  int id = ast_framehook_attach(channel, &interface);
53 \endcode
54 
55  The ast_framehook_attach() function creates and attaches a new FrameHook onto
56  a channel. Once attached to the channel, the FrameHook will call the event_callback
57  function each time a frame is written or read on the channel. A custom data
58  pointer can be provided to this function to store on the FrameHook as well. This
59  pointer can be used to keep up with any statefull information associated with the FrameHook
60  and is provided during the event_callback function. The destroy_callback function is optional.
61  This function exists so any custom data stored on the FrameHook can be destroyed before
62  the Framehook if destroyed.
63 
64 \code
65  ast_framehook_detach(channel, id);
66 \endcode
67 
68  The ast_framehook_detach() function signals the FrameHook represented by an id to
69  be detached and destroyed on a channel. Since it is possible this function may be called
70  during the FrameHook's event callback, it is impossible to synchronously detach the
71  FrameHook from the channel during this function call. It is guaranteed that the next
72  event proceeding the ast_framehook_detach() will be of type AST_FRAMEHOOK_EVENT_DETACH,
73  and that after that event occurs no other event will ever be issued for that FrameHook.
74  Once the FrameHook is destroyed, the destroy callback function will be called if it was
75  provided. Note that if this function is never called, the FrameHook will be detached
76  on channel destruction.
77 
78 \section FrameHookAPICodeExample FrameHook Example Code
79  The example code below attaches an FrameHook on a channel, and then detachs it when
80  the first ast_frame is read or written to the event callback function. The Framehook's id
81  is stored on the FrameHook's data pointer so it can be detached within the callback.
82 
83 \code
84  static void destroy_cb(void *data) {
85  ast_free(data);
86  }
87 
88  static struct ast_frame *event_cb(struct ast_channel *chan,
89  struct ast_frame *frame,
90  enum ast_framehook_event event,
91  void *data) {
92 
93  int *id = data;
94 
95  if (!frame) {
96  return frame;
97  }
98 
99  if (event == AST_FRAMEHOOK_EVENT_WRITE) {
100  ast_log(LOG_NOTICE, "YAY we received a frame in the write direction, Type: %d\n", frame->frametype)
101  ast_framehook_detach(chan, id); // the channel is guaranteed to be locked during this function call.
102  } else if (event == AST_FRAMEHOOK_EVENT_READ) {
103  ast_log(LOG_NOTICE, "YAY we received a frame in the read direction: Type: %d\n", frame->frametype);
104  ast_framehook_detach(chan, id); // the channel is guaranteed to be locked during this function call.
105  }
106 
107  return frame;
108  {
109 
110  int some_function()
111  {
112  struct ast_framehook_interface interface = {
113  .version = AST_FRAMEHOOK_INTERFACE_VERSION,
114  .event_cb = hook_event_cb,
115  .destroy_cb = hook_destroy_cb,
116  };
117  int *id = ast_calloc(1, sizeof(int));
118 
119  if (!id) {
120  return -1;
121  }
122 
123  interface.data = id; // This data will be returned to us in the callbacks.
124 
125  ast_channel_lock(chan);
126  *id = ast_framehook_attach(chan, &interface);
127  ast_channel_unlock(chan);
128 
129  if (*id < 0) {
130  // framehook attach failed, free data
131  ast_free(id);
132  return -1;
133  }
134  return 0;
135  }
136 \endcode
137 */
138 
139 #ifndef _AST_FRAMEHOOK_H_
140 #define _AST_FRAMEHOOK_H_
141 #include "asterisk/linkedlists.h"
142 #include "asterisk/frame.h"
143 
144 struct ast_framehook;
145 struct ast_framehook_list;
146 
147 /*!
148  * \brief These are the types of events that the framehook's event callback can receive
149  * \since 1.8
150  */
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 };
157 
158 /*!
159  * \brief This callback is called every time an event occurs on the framehook.
160  * \since 1.8
161  *
162  * \details Two events are guaranteed to occur once the ast_framehook_attach()
163  * function is called. These events are AST_FRAMEHOOK_EVENT_ATTACHED, which occurs
164  * immediately after the framehook is attached to a channel, and
165  * AST_FRAMEHOOK_EVENT_DETACHED, which occurs right after the framehook is
166  * detached.
167  *
168  * It is completely valid for the frame variable to be set to NULL. Always do a NULL
169  * check on the frame before attempted to access it. When the frame variable is present,
170  * it is safe to view and manipulate that frame in any way possible. It is even safe
171  * to return a completely different frame, but when that occurs this function is in
172  * charge of freeing the previous frame.
173  *
174  * The ast_channel will always be locked during this callback. Never attempt to unlock the
175  * channel for any reason.
176  *
177  * \param channel, The ast_channel this framehook is attached to
178  * \param frame, The ast_frame being intercepted for viewing and manipulation
179  * \param event, The type of event which is occurring
180  * \param data, The data pointer provided at framehook initilization.
181  *
182  * \retval the resulting frame.
183  */
184 typedef struct ast_frame *(*ast_framehook_event_callback)(
185  struct ast_channel *chan,
186  struct ast_frame *frame,
188  void *data);
189 
190 /*!
191  * \brief This callback is called immediately before the framehook is destroyed.
192  * \since 1.8
193  * \note This function should be used to clean up any pointers pointing to the
194  * framehook structure as the framehook will be freed immediately afterwards.
195  *
196  * \param data, The data pointer provided at framehook initialization. This
197  * is a good place to clean up any state data allocated for the framehook stored in this
198  * pointer.
199  */
200 typedef void (*ast_framehook_destroy_callback)(void *data);
201 
202 /*!
203  * \brief This callback is called to determine if the framehook is currently consuming
204  * frames of a given type
205  * \since 12
206  *
207  * \param data, The data pointer provided at framehook initilization.
208  * \param type, The type of frame.
209  *
210  * \return 0 if frame type is being ignored
211  * \return 1 if frame type is not being ignored
212  */
214 
215 /*!
216  * \brief This callback is called when a masquerade occurs on a channel with a framehook
217  * \since 12
218  *
219  * \param data, The data pointer provided at framehook initialization.
220  * \param framehook_id, The framehook ID where the framehook lives now
221  * \param old_chan, The channel that was masqueraded.
222  * \param new_chan, The channel that the masqueraded channel became.
223  */
224 typedef void (*ast_framehook_chan_fixup_callback)(void *data, int framehook_id,
225  struct ast_channel *old_chan, struct ast_channel *new_chan);
226 
227 #define AST_FRAMEHOOK_INTERFACE_VERSION 4
228 /*! This interface is required for attaching a framehook to a channel. */
230  /*! framehook interface version number */
231  uint16_t version;
232  /*! event_cb represents the function that will be called everytime an event occurs on the framehook. */
234  /*! destroy_cb is optional. This function is called immediately before the framehook
235  * is destroyed to allow for stored_data cleanup. */
237  /*! consume_cb is optional. This function is called to query whether the framehook is consuming
238  * frames of a specific type at this time. If this callback is not implemented it is assumed that the
239  * framehook will consume frames of all types. */
241  /*! chan_fixup_cb is optional. This function is called when the channel that a framehook is running
242  * on is masqueraded and should be used to move any essential framehook data onto the channel the
243  * old channel was masqueraded to. */
245  /*! chan_breakdown_cb is optional. This function is called when another channel is masqueraded into
246  * the channel that a framehook is running on and should be used to evaluate whether the framehook
247  * should remain on the channel. */
249  /*! disable_inheritance is optional. If set to non-zero, when a channel using this framehook is
250  * masqueraded, detach and destroy the framehook instead of moving it to the new channel. */
252  /*! This pointer can represent any custom data to be stored on the !framehook. This
253  * data pointer will be provided during each event callback which allows the framehook
254  * to store any stateful data associated with the application using the hook. */
255  void *data;
256 };
257 
258 /*!
259  * \brief Attach an framehook onto a channel for frame interception.
260  * \since 1.8
261  *
262  * \param chan ast_channel The channel to attach the hook on to.
263  * \param i framehook interface, The framehook's callback functions and stored data.
264  *
265  * \pre The Channel must be locked during this function call.
266  *
267  * \note The data pointer is never touched by the framehook API except to
268  * provide it during the event and destruction callbacks. It is entirely up to the
269  * application using this API to manage the memory associated with the data pointer.
270  *
271  * \retval On success, non-negative id representing this hook on the channel
272  * \retval On failure, -1
273  */
274 int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i);
275 
276 /*!
277  * \brief Detach an framehook from a channel.
278  * \since 1.8
279  *
280  * \pre The Channel must be locked during this function call.
281  * If this function is never called after attaching an framehook,
282  * the framehook will be detached and destroyed during channel
283  * destruction.
284  *
285  * \param chan The channel the framehook is attached to
286  * \param framehook_id The framehook's id
287  *
288  * \retval 0 success
289  * \retval -1 framehook did not exist on the channel. This means the
290  * framehook either never existed on the channel, or was already detached.
291  */
292 int ast_framehook_detach(struct ast_channel *chan, int framehook_id);
293 
294 /*!
295  * \brief This is used by the channel API to detach and destroy all
296  * framehooks on a channel during channel destruction.
297  * \since 1.8
298  *
299  * \pre The Channel must be locked during this function call.
300  *
301  * \param chan channel containing the framehook list to destroy.
302  * \retval 0 success
303  * \retval -1 failure
304  */
305 int ast_framehook_list_destroy(struct ast_channel *chan);
306 
307 /*!
308  * \brief This is used by the channel API during a masquerade operation
309  * to move all mobile framehooks from the original channel to the clone channel.
310  * \since 12.5.0
311  *
312  * \pre Both channels must be locked prior to this function call.
313  *
314  * \param old_chan The channel being cloned from
315  * \param new_chan The channel being cloned to
316  */
317 void ast_framehook_list_fixup(struct ast_channel *old_chan, struct ast_channel *new_chan);
318 
319 /*!
320  * \brief This is used by the channel API push a frame read event to a channel's framehook list.
321  * \since 1.8
322  *
323  * \details After this function completes, the resulting frame that is returned could be anything,
324  * even NULL. There is nothing to keep up with after this function. If the frame is modified, the
325  * framehook callback is in charge of any memory management associated with that modification.
326  *
327  * \pre The Channel must be locked during this function call.
328  *
329  * \param framehooks list to push event to.
330  * \param frame being pushed to the framehook list.
331  *
332  * \return The resulting frame after being viewed and modified by the framehook callbacks.
333  */
334 struct ast_frame *ast_framehook_list_read_event(struct ast_framehook_list *framehooks, struct ast_frame *frame);
335 
336 /*!
337  * \brief This is used by the channel API push a frame write event to a channel's framehook list.
338  * \since 1.8
339  *
340  * \details After this function completes, the resulting frame that is returned could be anything,
341  * even NULL. There is nothing to keep up with after this function. If the frame is modified, the
342  * framehook callback is in charge of any memory management associated with that modification.
343  *
344  * \pre The Channel must be locked during this function call.
345  *
346  * \param framehooks list to push event to.
347  * \param frame being pushed to the framehook list.
348  *
349  * \return The resulting frame after being viewed and modified by the framehook callbacks.
350  */
351 struct ast_frame *ast_framehook_list_write_event(struct ast_framehook_list *framehooks, struct ast_frame *frame);
352 
353 /*!
354  * \brief Determine if an framehook list is empty or not
355  * \since 1.8
356  * \pre The Channel must be locked during this function call.
357  *
358  * \param framehooks the framehook list
359  * \retval 0, not empty
360  * \retval 1, is empty
361  */
362 int ast_framehook_list_is_empty(struct ast_framehook_list *framehooks);
363 
364 /*!
365  * \brief Determine if a framehook list is free of active framehooks or not
366  * \since 12.0.0
367  * \pre The channel must be locked during this function call.
368  *
369  * \param framehooks the framehook list
370  * \retval 0, not empty
371  * \retval 1, is empty (aside from dying framehooks)
372  *
373  * \note This function is very similar to ast_framehook_list_is_empty, but it checks individual
374  * framehooks to see if they have been marked for destruction and doesn't count them if they are.
375  */
377 
378 /*!
379  * \brief Determine if a framehook list is free of active framehooks consuming a specific type of frame
380  * \since 12.3.0
381  * \pre The channel must be locked during this function call.
382  *
383  * \param framehooks the framehook list
384  * \retval 0, not empty
385  * \retval 1, is empty (aside from dying framehooks)
386  *
387  * \note This function is very similar to ast_framehook_list_is_empty, but it checks individual
388  * framehooks to see if they have been marked for destruction and doesn't count them if they are.
389  */
391  enum ast_frame_type type);
392 
393 #endif /* _AST_FRAMEHOOK_H */
static const char type[]
Definition: chan_ooh323.c:109
ast_framehook_event_callback event_cb
Definition: framehook.h:233
Main Channel structure associated with a channel.
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.
Definition: framehook.h:184
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.
Definition: framehook.h:224
int ast_framehook_list_is_empty(struct ast_framehook_list *framehooks)
Determine if an framehook list is empty or not.
Definition: framehook.c:274
ast_framehook_event
These are the types of events that the framehook&#39;s event callback can receive.
Definition: framehook.h:151
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Definition: framehook.c:177
Definition: astman.c:222
ast_framehook_destroy_callback destroy_cb
Definition: framehook.h:236
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 dest...
Definition: framehook.c:206
void(* ast_framehook_destroy_callback)(void *data)
This callback is called immediately before the framehook is destroyed.
Definition: framehook.h:200
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
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
Asterisk internal frame definitions.
A set of macros to manage forward-linked lists.
ast_frame_type
Frame types.
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 ...
Definition: framehook.c:223
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&#39;s framehook list...
Definition: framehook.c:313
ast_framehook_chan_fixup_callback chan_fixup_cb
Definition: framehook.h:244
ast_framehook_chan_fixup_callback chan_breakdown_cb
Definition: framehook.h:248
int ast_framehook_list_contains_no_active(struct ast_framehook_list *framehooks)
Determine if a framehook list is free of active framehooks or not.
Definition: framehook.c:282
ast_framehook_consume_callback consume_cb
Definition: framehook.h:240
Data structure associated with a single frame of data.
union ast_frame::@263 data
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...
Definition: framehook.h:213
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&#39;s framehook list.
Definition: framehook.c:318