[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