[asterisk-commits] dvossel: branch dvossel/awesomehooks r287552 - in /team/dvossel/awesomehooks:...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Sep 20 10:18:49 CDT 2010


Author: dvossel
Date: Mon Sep 20 10:18:46 2010
New Revision: 287552

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=287552
Log:
introduction of ast_framehook_interface struct plus new documentation

Modified:
    team/dvossel/awesomehooks/funcs/func_frame_trace.c
    team/dvossel/awesomehooks/include/asterisk/framehook.h
    team/dvossel/awesomehooks/main/framehook.c

Modified: team/dvossel/awesomehooks/funcs/func_frame_trace.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/awesomehooks/funcs/func_frame_trace.c?view=diff&rev=287552&r1=287551&r2=287552
==============================================================================
--- team/dvossel/awesomehooks/funcs/func_frame_trace.c (original)
+++ team/dvossel/awesomehooks/funcs/func_frame_trace.c Mon Sep 20 10:18:46 2010
@@ -92,7 +92,7 @@
 	{ AST_FRAME_MODEM,   "MODEM" },
 };
 
-struct awesome_trace_data {
+struct frame_trace_data {
 	int list_type; /* 0 = white, 1 = black */
 	int values[ARRAY_LEN(frametype2str)];
 };
@@ -101,21 +101,21 @@
 	ast_free(data);
 }
 
-static const struct ast_datastore_info awesome_trace_datastore = {
-	.type = "awesometrace",
+static const struct ast_datastore_info frame_trace_datastore = {
+	.type = "frametrace",
 	.destroy = datastore_destroy_cb
 };
 
-static void hook_destroy_cb(void *awesomedata)
-{
-	ast_free(awesomedata);
-}
-
-static struct ast_frame *hook_event_cb(struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *datastore)
+static void hook_destroy_cb(void *framedata)
+{
+	ast_free(framedata);
+}
+
+static struct ast_frame *hook_event_cb(struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
 {
 	int i;
 	int show_frame = 0;
-	struct awesome_trace_data *awesomedata = datastore;
+	struct frame_trace_data *framedata = data;
 	if (!frame) {
 		return frame;
 	}
@@ -126,9 +126,9 @@
 
 	for (i = 0; i < ARRAY_LEN(frametype2str); i++) {
 		if (frame->frametype == frametype2str[i].type) {
-			if ((awesomedata->list_type == 0) && (awesomedata->values[i])) { /* white list */
+			if ((framedata->list_type == 0) && (framedata->values[i])) { /* white list */
 				show_frame = 1;
-			} else if ((awesomedata->list_type == 1) && (!awesomedata->values[i])){ /* black list */
+			} else if ((framedata->list_type == 1) && (!framedata->values[i])){ /* black list */
 				show_frame = 1;
 			}
 			break;
@@ -142,36 +142,43 @@
 	return frame;
 }
 
-static int awesome_trace_helper(struct ast_channel *chan, const char *cmd, char *data, const char *value)
-{
-	struct awesome_trace_data *awesomedata;
+static int frame_trace_helper(struct ast_channel *chan, const char *cmd, char *data, const char *value)
+{
+	struct frame_trace_data *framedata;
 	struct ast_datastore *datastore = NULL;
+	struct ast_framehook_interface interface = {
+		.version = AST_FRAMEHOOK_INTERFACE_VERSION,
+		.event_cb = hook_event_cb,
+		.destroy_cb = hook_destroy_cb,
+	};
 	int i = 0;
 
-	if (!(awesomedata = ast_calloc(1, sizeof(*awesomedata)))) {
+	if (!(framedata = ast_calloc(1, sizeof(*framedata)))) {
 		return 0;
 	}
 
+	interface.data = framedata;
+
 	if (!strcasecmp(data, "black")) {
-		awesomedata->list_type = 1;
+		framedata->list_type = 1;
 	}
 	for (i = 0; i < ARRAY_LEN(frametype2str); i++) {
 		if (strcasestr(value, frametype2str[i].str)) {
-			awesomedata->values[i] = 1;
+			framedata->values[i] = 1;
 		}
 	}
 
 	ast_channel_lock(chan);
-	i = ast_framehook_attach(chan, hook_event_cb, hook_destroy_cb, awesomedata);
+	i = ast_framehook_attach(chan, &interface);
 	if (i >= 0) {
 		int *id;
-		if ((datastore = ast_channel_datastore_find(chan, &awesome_trace_datastore, NULL))) {
+		if ((datastore = ast_channel_datastore_find(chan, &frame_trace_datastore, NULL))) {
 			id = datastore->data;
 			ast_framehook_detach(chan, *id);
 			ast_channel_datastore_remove(chan, datastore);
 		}
 
-		if (!(datastore = ast_datastore_alloc(&awesome_trace_datastore, NULL))) {
+		if (!(datastore = ast_datastore_alloc(&frame_trace_datastore, NULL))) {
 			ast_framehook_detach(chan, i);
 			ast_channel_unlock(chan);
 			return 0;
@@ -338,19 +345,19 @@
 	ast_verbose("\n");
 }
 
-static struct ast_custom_function awesome_trace_function = {
+static struct ast_custom_function frame_trace_function = {
 	.name = "FRAME_TRACE",
-	.write = awesome_trace_helper,
+	.write = frame_trace_helper,
 };
 
 static int unload_module(void)
 {
-	return ast_custom_function_unregister(&awesome_trace_function);
+	return ast_custom_function_unregister(&frame_trace_function);
 }
 
 static int load_module(void)
 {
-	int res = ast_custom_function_register(&awesome_trace_function);
+	int res = ast_custom_function_register(&frame_trace_function);
 	return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
 }
 

Modified: team/dvossel/awesomehooks/include/asterisk/framehook.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/awesomehooks/include/asterisk/framehook.h?view=diff&rev=287552&r1=287551&r2=287552
==============================================================================
--- team/dvossel/awesomehooks/include/asterisk/framehook.h (original)
+++ team/dvossel/awesomehooks/include/asterisk/framehook.h Mon Sep 20 10:18:46 2010
@@ -27,7 +27,13 @@
 \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. 
+    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
@@ -37,12 +43,18 @@
     functions and their usage.
 
 \code
-    int id = ast_framehook_attach(channel, event_callback, destroy_callback, datastore);
+	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 datastore
+    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.
@@ -69,16 +81,16 @@
     is stored on the FrameHook's data pointer so it can be detached within the callback.
 
 \code
-    static void destroy_cb(void *datastore) {
-	    ast_free(datastore);
+    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 *datastore) {
+            void *data) {
    
-        int *id = datastore;
+        int *id = data;
 
         if (!frame) {
             return frame;
@@ -96,14 +108,21 @@
     {
 
     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, event_cb, destroy_cb, id);
+        *id = ast_framehook_attach(chan, &interface);
         ast_channel_unlock(chan);
 
         if (*id < 0) {
@@ -159,7 +178,7 @@
  * \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 datastore, The datastore pointer provided at framehook initilization.
+ * \param data, The data pointer provided at framehook initilization.
  *
  * \retval the resulting frame.
  */
@@ -167,45 +186,51 @@
 	struct ast_channel *chan,
 	struct ast_frame *frame,
 	enum ast_framehook_event event,
-	void *datastore);
+	void *data);
 
 /*!
  * \brief This callback is called immediately before the framehook is destroyed.
  * \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 datastore, The datastore pointer provided at framehook initialization. This
+ * \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 *datastore);
+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.
  *
  * \param ast_channel, The channel to attach the hook on to.
- * \param event_cb represents the function that will be called everytime an
- * event occurs on the framehook.
- * \param destroy_cb is optional.  This function is called immediately before the
- * framehook is destroyed to allow for datastore cleanup.
- * \param 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.
- *
- * \note XXX The Channel must be locked during this function all.
- *
- * \note The datastore pointer is never touched by the framehook API except to
+ * \param framehook interface, The framehook's callback functions and stored data.
+*
+ * \note 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 datastore pointer.
+ * 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,
-	ast_framehook_event_callback event_cb,
-	ast_framehook_destroy_callback destroy_cb,
-	void *datastore);
+int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i);
 
 /*!
  * \brief Detach an framehook from a channel.

Modified: team/dvossel/awesomehooks/main/framehook.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/awesomehooks/main/framehook.c?view=diff&rev=287552&r1=287551&r2=287552
==============================================================================
--- team/dvossel/awesomehooks/main/framehook.c (original)
+++ team/dvossel/awesomehooks/main/framehook.c Mon Sep 20 10:18:46 2010
@@ -33,8 +33,9 @@
 #include "asterisk/frame.h"
 
 struct ast_framehook {
+	uint16_t version;
 	/*! This pointer holds any stateful data an application wishes to store. */
-	void *datastore;
+	void *data;
 	/*! This pointer to ast_channel the framehook is attached to. */
 	struct ast_channel *chan;
 	/*! the id representing this framehook on a channel */
@@ -52,7 +53,7 @@
 static void framehook_detach_and_destroy(struct ast_framehook *framehook)
 {
 	struct ast_frame *frame;
-	frame = framehook->event_cb(framehook->chan, NULL, AST_FRAMEHOOK_EVENT_DETACHED, framehook->datastore);
+	frame = framehook->event_cb(framehook->chan, NULL, AST_FRAMEHOOK_EVENT_DETACHED, framehook->data);
 	/* never assume anything about this function. If you can return a frame during
 	 * the detached event, then assume someone will. */
 	if (frame) {
@@ -61,7 +62,7 @@
 	framehook->chan = NULL;
 
 	if (framehook->destroy_cb) {
-		framehook->destroy_cb(framehook->datastore);
+		framehook->destroy_cb(framehook->data);
 	}
 	ast_free(framehook);
 }
@@ -75,30 +76,31 @@
 			AST_LIST_REMOVE_CURRENT(list);
 			framehook_detach_and_destroy(framehook);
 		} else {
-			frame = framehook->event_cb(framehook->chan, frame, event, framehook->datastore);
+			frame = framehook->event_cb(framehook->chan, frame, event, framehook->data);
 		}
 	}
 	AST_LIST_TRAVERSE_SAFE_END;
 	return frame;
 }
 
-int ast_framehook_attach(struct ast_channel *chan, ast_framehook_event_callback event_cb, ast_framehook_destroy_callback destroy_cb, void *data)
+int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
 {
 	struct ast_framehook *framehook;
 	struct ast_frame *frame;
-	if (!event_cb || !(framehook = ast_calloc(1, sizeof(*framehook)))) {
+	if (!i->event_cb || !(framehook = ast_calloc(1, sizeof(*framehook)))) {
 		return -1;
 	}
-	framehook->event_cb = event_cb;
-	framehook->destroy_cb = destroy_cb;
-	framehook->datastore = data;
+	framehook->version = i->version;
+	framehook->event_cb = i->event_cb;
+	framehook->destroy_cb = i->destroy_cb;
+	framehook->data = i->data;
 	framehook->chan = chan;
 	framehook->id = ++chan->framehooks.id_count;
 
 	AST_LIST_INSERT_TAIL(&chan->framehooks.list, framehook, list);
 
 	/* Tell the event callback we're live and rocking */
-	frame = framehook->event_cb(framehook->chan, NULL, AST_FRAMEHOOK_EVENT_ATTACHED, framehook->datastore);
+	frame = framehook->event_cb(framehook->chan, NULL, AST_FRAMEHOOK_EVENT_ATTACHED, framehook->data);
 
 	/* Never assume anything about this function. If you can return a frame during
 	 * the attached event, then assume someone will. */




More information about the asterisk-commits mailing list