[asterisk-commits] file: branch group/bridging_api r56456 - in /team/group/bridging_api: bridges...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Fri Feb 23 14:28:25 MST 2007


Author: file
Date: Fri Feb 23 15:28:24 2007
New Revision: 56456

URL: http://svn.digium.com/view/asterisk?view=rev&rev=56456
Log:
Bring bridging API branch up to date with local copy.

Modified:
    team/group/bridging_api/bridges/bridge_simple.c
    team/group/bridging_api/include/asterisk/bridging.h
    team/group/bridging_api/main/bridging.c

Modified: team/group/bridging_api/bridges/bridge_simple.c
URL: http://svn.digium.com/view/asterisk/team/group/bridging_api/bridges/bridge_simple.c?view=diff&rev=56456&r1=56455&r2=56456
==============================================================================
--- team/group/bridging_api/bridges/bridge_simple.c (original)
+++ team/group/bridging_api/bridges/bridge_simple.c Fri Feb 23 15:28:24 2007
@@ -42,18 +42,39 @@
 
 static int simple_bridge_create(struct ast_bridge *br)
 {
+	/* A simple bridge does not need to keep any data for itself */
+	br->data = NULL;
+
+	return 0;
+}
+
+static int simple_bridge_join(struct ast_bridge *br, struct ast_bridge_channel *bc)
+{
+	return -1;
+}
+
+static int simple_bridge_unjoin(struct ast_bridge *br, struct ast_bridge_channel *bc)
+{
+	return -1;
+}
+
+static int simple_bridge_thread(struct ast_bridge *br)
+{
 	return -1;
 }
 
 static int simple_bridge_destroy(struct ast_bridge *br)
 {
-	return -1;
+	return 0;
 }
 
 static struct ast_bridge_type simple_bridge_type = {
 	.name = "simple",
 	.capabilities = AST_BRIDGE_CAPABILITY_1TO1,
 	.create = simple_bridge_create,
+	.join = simple_bridge_join,
+	.unjoin = simple_bridge_unjoin,
+	.thread = simple_bridge_thread,
 	.destroy = simple_bridge_destroy,
 };
 

Modified: team/group/bridging_api/include/asterisk/bridging.h
URL: http://svn.digium.com/view/asterisk/team/group/bridging_api/include/asterisk/bridging.h?view=diff&rev=56456&r1=56455&r2=56456
==============================================================================
--- team/group/bridging_api/include/asterisk/bridging.h (original)
+++ team/group/bridging_api/include/asterisk/bridging.h Fri Feb 23 15:28:24 2007
@@ -24,27 +24,35 @@
 #define _ASTERISK_BRIDGING_H
 
 struct ast_bridge_channel {
-	struct ast_channel *chan;
-	AST_LIST_ENTRY(ast_bridge_channel) list;
+	struct ast_channel *chan;                /*!< Asterisk channel involved in bridge */
+	void *data;                              /*!< Bridge type specific data */
+	AST_LIST_ENTRY(ast_bridge_channel) list; /*!< Linked list information for bridged channels */
 };
 
 struct ast_bridge {
-	struct ast_bridge_type *bt;
-	AST_LIST_HEAD_NOLOCK(, ast_bridge_channel) bridge_channels;
+	ast_mutex_t lock;                                           /*!< Bridge lock */
+	ast_cond_t cond;                                            /*!< Bridge condition */
+	pthread_t thread;                                           /*!< Bridge thread */
+	struct ast_bridge_type *bt;                                 /*!< Technology behind this bridge */
+	void *data;                                                 /*!< Bridge type specific data */
+	AST_LIST_HEAD_NOLOCK(, ast_bridge_channel) bridge_channels; /*!< Channels involved in the bridge */
 };
 
 enum ast_bridge_capabilities {
-	AST_BRIDGE_CAPABILITY_1TO1 = (1 << 0),
-	AST_BRIDGE_CAPABILITY_MULTIMIX = (1 << 1),
+	AST_BRIDGE_CAPABILITY_1TO1 = (1 << 0),     /*!< Bridge type is capable of having one channel talk to another */
+	AST_BRIDGE_CAPABILITY_MULTIMIX = (1 << 1), /*!< Bridge type is capable of having multiple channels talk to one another */
 };
 
 struct ast_bridge_type {
-        const char *name;               /*!< Name */
-	int capabilities;               /*!< Bridge capabilities */
-	struct ast_module *module;      /*!< Module that the bridge type belongs to */
-	int (*create)(struct ast_bridge *br);
-	int (*destroy)(struct ast_bridge *br);
-        AST_RWLIST_ENTRY(ast_bridge_type) list;
+        const char *name;                                                    /*!< Name */
+	int capabilities;                                                    /*!< Bridge capabilities */
+	struct ast_module *module;                                           /*!< Module that the bridge type belongs to */
+	int (*create)(struct ast_bridge *br);                                /*!< Called when the bridge is initially created */
+	int (*join)(struct ast_bridge *br, struct ast_bridge_channel *bc);   /*!< Called when a channel is joined to the bridge */
+	int (*unjoin)(struct ast_bridge *br, struct ast_bridge_channel *bc); /*!< Called when a channel is unjoined from the bridge */
+	int (*destroy)(struct ast_bridge *br);                               /*!< Called when the bridge is being torn down */
+	int (*thread)(struct ast_bridge *br);                                /*!< Function that is run for the entirety of the bridge */
+        AST_RWLIST_ENTRY(ast_bridge_type) list;                              /*!< Linked list information for bridge types */
 };
 
 /*! \brief Registers a bridge type
@@ -66,6 +74,20 @@
  */
 struct ast_bridge *ast_bridge_create(int capabilities);
 
+/*! \brief Join a channel to a bridge
+ * \param br Bridge to join to
+ * \param chan Channel to join in
+ * \return 0 on success, -1 on failure
+ */
+int ast_bridge_join(struct ast_bridge *br, struct ast_channel *chan);
+
+/*! \brief Unjoin a channel from a bridge
+ * \param br Bridge to unjoin from
+ * \param chan Channel to unjoin
+ * \return 0 on success, -1 on failure
+ */
+int ast_bridge_unjoin(struct ast_bridge *br, struct ast_channel *chan);
+
 /*! \brief Destroy a bridge
  * \param br Bridge to destroy
  * \return Returns 0 on success, -1 on failure

Modified: team/group/bridging_api/main/bridging.c
URL: http://svn.digium.com/view/asterisk/team/group/bridging_api/main/bridging.c?view=diff&rev=56456&r1=56455&r2=56456
==============================================================================
--- team/group/bridging_api/main/bridging.c (original)
+++ team/group/bridging_api/main/bridging.c Fri Feb 23 15:28:24 2007
@@ -46,6 +46,26 @@
 
 static AST_RWLIST_HEAD_STATIC(bridge_types, ast_bridge_type);
 
+static void *bridge_thread(void *data)
+{
+	struct ast_bridge *br = data;
+
+	/* This is rather simple... we just call the thread function of the bridge type */
+	br->bt->thread(br);
+
+	return NULL;
+}
+
+static void bridge_channel_free(struct ast_bridge_channel *bc)
+{
+	/* If this channel is running in async, we hang it up */
+
+	/* Free ourselves */
+	free(bc);
+
+	return;
+}
+
 /*! \brief Registers a bridge type
  * \param bt Bridge type to register
  * \param mod Module that bridge type belongs to
@@ -54,6 +74,12 @@
 int ast_bridge_type_register(struct ast_bridge_type *bt, struct ast_module *mod)
 {
 	struct ast_bridge_type *bridge_type;
+
+	/* Perform sanity check on bridge type */
+	if (!bt->thread) {
+		ast_log(LOG_ERROR, "Bridge type %s is missing vital thread function.\n", bt->name);
+		return -1;
+	}
 
 	/* Since our module information couldn't be statically declared when compiled... we have to set the value here */
 	bt->module = mod;
@@ -158,7 +184,97 @@
 	/* Make the bridge type part of this bridge */
 	br->bt = bt;
 
+	/* Initialize other bridge variables */
+	br->thread = AST_PTHREADT_NULL;
+	ast_mutex_init(&br->lock);
+	ast_cond_init(&br->cond, NULL);
+	AST_LIST_HEAD_INIT_NOLOCK(&br->bridge_channels);
+
+	/* Tell the bridge type to setup this bridge for their own purposes */
+	if (br->bt->create && br->bt->create(br)) {
+		ast_module_unref(bt->module);
+		free(br);
+		return NULL;
+	}
+
+	/* Start the thread that will take over the bridge */
+	if (ast_pthread_create(&br->thread, NULL, bridge_thread, br) < 0) {
+		ast_module_unref(bt->module);
+		free(br);
+		return NULL;
+	}
+
 	return br;
+}
+
+/*! \brief Join a channel to a bridge
+ * \param br Bridge to join to
+ * \param chan Channel to join in
+ * \return 0 on success, -1 on failure
+ */
+int ast_bridge_join(struct ast_bridge *br, struct ast_channel *chan)
+{
+	struct ast_bridge_channel *bc = NULL;
+
+	/* Allocate memory for a new bridge channel structure and setup default values */
+	if (!(bc = ast_calloc(1, sizeof(*bc))))
+		return -1;
+
+	bc->chan = chan;
+
+	ast_mutex_lock(&br->lock);
+
+	/* Add them to the bridged channel list */
+	AST_LIST_INSERT_TAIL(&br->bridge_channels, bc, list);
+
+	/* Talk to the bridge type and notify them that this channel is joining the bridge */
+	if (br->bt->join && br->bt->join(br, bc)) {
+		free(bc);
+		ast_mutex_unlock(&br->lock);
+		return -1;
+	}
+
+	ast_mutex_unlock(&br->lock);
+
+	return 0;
+}
+
+/*! \brief Unjoin a channel from a bridge
+ * \param br Bridge to unjoin from
+ * \param chan Channel to unjoin
+ * \return 0 on success, -1 on failure
+ */
+int ast_bridge_unjoin(struct ast_bridge *br, struct ast_channel *chan)
+{
+	struct ast_bridge_channel *bc = NULL;
+
+	ast_mutex_lock(&br->lock);
+
+	/* Look for this channel in the bridge channel list */
+	AST_LIST_TRAVERSE(&br->bridge_channels, bc, list) {
+		if (bc->chan == chan)
+			break;
+	}
+
+	/* If no bridge channel structure was found then they aren't here... c'est la vie */
+	if (!bc) {
+		ast_mutex_unlock(&br->lock);
+		return -1;
+	}
+
+	/* Notify bridge type that this channel is unjoining */
+	if (br->bt->unjoin && br->bt->unjoin(br, bc))
+		ast_log(LOG_WARNING, "Failed to unjoin %s from bridge %p... bad things may happen.\n", chan->name, br);
+
+	/* Remove channel from list */
+	AST_LIST_REMOVE(&br->bridge_channels, bc, list);
+
+	ast_mutex_unlock(&br->lock);
+
+	/* We can leave the bridge alone now and just focus on freeing or hanging up this bridged channel */
+	bridge_channel_free(bc);
+
+	return 0;
 }
 
 /*! \brief Destroy a bridge
@@ -167,5 +283,28 @@
  */
 int ast_bridge_destroy(struct ast_bridge *br)
 {
-	return -1;
-}
+	struct ast_bridge_channel *bc = NULL;
+
+	/* Stop the bridge thread */
+	if (br->thread != AST_PTHREADT_NULL) {
+	}
+
+	/* Unjoin every bridged channel */
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&br->bridge_channels, bc, list) {
+		AST_LIST_REMOVE_CURRENT(&br->bridge_channels, list);
+		/* Notify bridge type that this channel is unjoining */
+		if (br->bt->unjoin && br->bt->unjoin(br, bc))
+			ast_log(LOG_WARNING, "Failed to unjoin %s from bridge %p... bad things may happen.\n", bc->chan->name, br);
+		bridge_channel_free(bc);
+	}
+	AST_LIST_TRAVERSE_SAFE_END
+
+	/* Tell the bridge type to destroy this bridge */
+	if (br->bt->destroy && br->bt->destroy(br))
+		ast_log(LOG_WARNING, "Bridge type failed to destroy %p - madness may happen.\n", br);
+
+	/* Remove reference from bridge type */
+	ast_module_unref(br->bt->module);
+
+	return 0;
+}



More information about the asterisk-commits mailing list