[asterisk-commits] kmoore: branch kmoore/bridge_construction-cel_channels r389327 - in /team/kmo...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon May 20 15:47:40 CDT 2013
Author: kmoore
Date: Mon May 20 15:47:36 2013
New Revision: 389327
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389327
Log:
Refactor to avoid ast_bridged_channel
This also includes a function (ast_channel_snapshot_get_latest) swiped
from dlee.
Modified:
team/kmoore/bridge_construction-cel_channels/include/asterisk/stasis_bridging.h
team/kmoore/bridge_construction-cel_channels/include/asterisk/stasis_channels.h
team/kmoore/bridge_construction-cel_channels/main/cel.c
team/kmoore/bridge_construction-cel_channels/main/stasis_bridging.c
team/kmoore/bridge_construction-cel_channels/main/stasis_channels.c
Modified: team/kmoore/bridge_construction-cel_channels/include/asterisk/stasis_bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_channels/include/asterisk/stasis_bridging.h?view=diff&rev=389327&r1=389326&r2=389327
==============================================================================
--- team/kmoore/bridge_construction-cel_channels/include/asterisk/stasis_bridging.h (original)
+++ team/kmoore/bridge_construction-cel_channels/include/asterisk/stasis_bridging.h Mon May 20 15:47:36 2013
@@ -45,6 +45,8 @@
struct ao2_container *channels;
/*! Bridge flags to tweak behavior */
struct ast_flags feature_flags;
+ /*! Bridge capabilities */
+ uint32_t capabilities;
/*! Number of channels participating in the bridge */
unsigned int num_channels;
/*! Number of active channels in the bridge. */
Modified: team/kmoore/bridge_construction-cel_channels/include/asterisk/stasis_channels.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_channels/include/asterisk/stasis_channels.h?view=diff&rev=389327&r1=389326&r2=389327
==============================================================================
--- team/kmoore/bridge_construction-cel_channels/include/asterisk/stasis_channels.h (original)
+++ team/kmoore/bridge_construction-cel_channels/include/asterisk/stasis_channels.h Mon May 20 15:47:36 2013
@@ -50,8 +50,6 @@
AST_STRING_FIELD(data); /*!< Data passed to current application */
AST_STRING_FIELD(context); /*!< Dialplan: Current extension context */
AST_STRING_FIELD(exten); /*!< Dialplan: Current extension number */
- AST_STRING_FIELD(bridged_name); /*!< The name of the channel bridged to this one */
- AST_STRING_FIELD(bridged_id); /*!< The uniqueid of the channel bridged to this one */
AST_STRING_FIELD(caller_name); /*!< Caller ID Name */
AST_STRING_FIELD(caller_number); /*!< Caller ID Number */
AST_STRING_FIELD(caller_ani); /*!< Caller ID ANI Number */
@@ -129,6 +127,18 @@
/*!
* \since 12
+ * \since 12
+ * \brief Get the most recent snapshot for channel with the given \a uniqueid.
+ *
+ * \param uniqueid Uniqueid of the snapshot to fetch.
+ * \return Most recent channel snapshot
+ * \return \c NULL on error
+ */
+struct ast_channel_snapshot *ast_channel_snapshot_get_latest(
+ const char *uniqueid);
+
+/*!
+ * \since 12
* \brief Creates a \ref ast_channel_blob message.
*
* The given \a blob should be treated as immutable and not modified after it is
Modified: team/kmoore/bridge_construction-cel_channels/main/cel.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_channels/main/cel.c?view=diff&rev=389327&r1=389326&r2=389327
==============================================================================
--- team/kmoore/bridge_construction-cel_channels/main/cel.c (original)
+++ team/kmoore/bridge_construction-cel_channels/main/cel.c Mon May 20 15:47:36 2013
@@ -71,6 +71,12 @@
/*! Subscription for forwarding the channel caching topic */
static struct stasis_subscription *cel_bridge_forwarder;
+
+/*! Container for primary channel/bridge ID listing for 2 party bridges */
+static struct ao2_container *bridge_primaries;
+
+/*! The number of buckets into which primary channel uniqueids will be hashed */
+#define BRIDGE_PRIMARY_BUCKETS 251
/*! Container for dial end multichannel blobs for holding on to dial statuses */
static struct ao2_container *cel_dialstatus_store;
@@ -156,6 +162,75 @@
[AST_CEL_LINKEDID_END] = "LINKEDID_END",
};
+struct bridge_assoc {
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(channel_id); /*!< UniqueID of the primary/dialing channel */
+ AST_STRING_FIELD(bridge_id); /*!< UniqueID of the bridge */
+ AST_STRING_FIELD(secondary_id); /*!< UniqueID of the secondary/dialed channel */
+ );
+};
+
+static void bridge_assoc_dtor(void *obj)
+{
+ struct bridge_assoc *assoc = obj;
+ ast_string_field_free_memory(assoc);
+}
+
+static struct bridge_assoc *bridge_assoc_alloc(const char *channel_id, const char *bridge_id, const char *secondary_id)
+{
+ RAII_VAR(struct bridge_assoc *, assoc, ao2_alloc(sizeof(*assoc), bridge_assoc_dtor), ao2_cleanup);
+ if (!assoc || ast_string_field_init(assoc, 64)) {
+ return NULL;
+ }
+
+ ast_string_field_set(assoc, channel_id, channel_id);
+ ast_string_field_set(assoc, bridge_id, bridge_id);
+ ast_string_field_set(assoc, secondary_id, secondary_id);
+
+ ao2_ref(assoc, +1);
+ return assoc;
+}
+
+static int add_bridge_primary(const char *channel_id, const char *bridge_id, const char *secondary_id)
+{
+ RAII_VAR(struct bridge_assoc *, assoc, bridge_assoc_alloc(channel_id, bridge_id, secondary_id), ao2_cleanup);
+ if (!assoc) {
+ return -1;
+ }
+
+ ao2_link(bridge_primaries, assoc);
+ return 0;
+}
+
+static void remove_bridge_primary(const char *channel_id)
+{
+ ao2_find(bridge_primaries, channel_id, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK);
+}
+
+/*! \brief Hashing function for bridge_assoc */
+static int bridge_assoc_hash(const void *obj, int flags)
+{
+ const struct bridge_assoc *assoc = obj;
+ const char *uniqueid = obj;
+ if (!(flags & OBJ_KEY)) {
+ uniqueid = assoc->channel_id;
+ }
+
+ return ast_str_hash(uniqueid);
+}
+
+/*! \brief Comparator function for bridge_assoc */
+static int bridge_assoc_cmp(void *obj, void *arg, int flags)
+{
+ struct bridge_assoc *assoc1 = obj, *assoc2 = arg;
+ const char *assoc2_id = arg, *assoc1_id = assoc1->channel_id;
+ if (!(flags & OBJ_KEY)) {
+ assoc2_id = assoc2->channel_id;
+ }
+
+ return !strcmp(assoc1_id, assoc2_id) ? CMP_MATCH | CMP_STOP : 0;
+}
+
static const char *get_caller_uniqueid(struct ast_multi_channel_blob *blob)
{
struct ast_channel_snapshot *caller = ast_multi_channel_blob_get_channel(blob, "caller");
@@ -429,9 +504,20 @@
struct timeval eventtime;
struct ast_event *ev;
char *linkedid = ast_strdupa(snapshot->linkedid);
+ char *peer_name = "";
+ RAII_VAR(struct bridge_assoc *, assoc, NULL, ao2_cleanup);
if (!cel_enabled) {
return 0;
+ }
+
+ assoc = ao2_find(bridge_primaries, snapshot->uniqueid, OBJ_KEY);
+ if (assoc) {
+ RAII_VAR(struct ast_channel_snapshot *, bridged_snapshot, NULL, ao2_cleanup);
+ bridged_snapshot = ast_channel_snapshot_get_latest(assoc->secondary_id);
+ if (bridged_snapshot) {
+ peer_name = ast_strdupa(bridged_snapshot->name);
+ }
}
/* Make sure a reload is not occurring while we're checking to see if this
@@ -488,7 +574,7 @@
AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, snapshot->linkedid,
AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, snapshot->userfield,
AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, S_OR(extra, ""),
- AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, snapshot->bridged_name,
+ AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peer_name,
AST_EVENT_IE_END);
if (ev && ast_event_queue(ev)) {
@@ -956,6 +1042,71 @@
}
}
+static void cel_bridge_enter_cb(
+ void *data, struct stasis_subscription *sub,
+ struct stasis_topic *topic,
+ struct stasis_message *message)
+{
+ struct ast_bridge_blob *blob = stasis_message_data(message);
+ struct ast_bridge_snapshot *snapshot = blob->bridge;
+ struct ast_channel_snapshot *chan_snapshot = blob->channel;
+
+ if (snapshot->capabilities | AST_BRIDGE_CAPABILITY_1TO1MIX || snapshot->capabilities | AST_BRIDGE_CAPABILITY_NATIVE) {
+ if (ao2_container_count(snapshot->channels) == 2) {
+ struct ao2_iterator i;
+ RAII_VAR(char *, channel_id, NULL, ao2_cleanup);
+
+ /* get the name of the channel in the container we don't already know the name of */
+ i = ao2_iterator_init(snapshot->channels, 0);
+ while ((channel_id = ao2_iterator_next(&i))) {
+ if (strcmp(channel_id, chan_snapshot->uniqueid)) {
+ break;
+ }
+ ao2_cleanup(channel_id);
+ channel_id = NULL;
+ }
+ ao2_iterator_destroy(&i);
+
+ add_bridge_primary(channel_id, snapshot->uniqueid, chan_snapshot->uniqueid);
+ }
+ }
+}
+
+static void cel_bridge_leave_cb(
+ void *data, struct stasis_subscription *sub,
+ struct stasis_topic *topic,
+ struct stasis_message *message)
+{
+ struct ast_bridge_blob *blob = stasis_message_data(message);
+ struct ast_bridge_snapshot *snapshot = blob->bridge;
+ struct ast_channel_snapshot *chan_snapshot = blob->channel;
+
+ if ((snapshot->capabilities | AST_BRIDGE_CAPABILITY_1TO1MIX)
+ || (snapshot->capabilities | AST_BRIDGE_CAPABILITY_NATIVE)) {
+ if (ao2_container_count(snapshot->channels) == 1) {
+ RAII_VAR(char *, ao2_primary, ao2_find(bridge_primaries, chan_snapshot->uniqueid, OBJ_KEY), ao2_cleanup);
+ RAII_VAR(char *, channel_id_in_bridge, NULL, ao2_cleanup);
+ char *primary;
+ struct ao2_iterator i;
+
+ /* get the only item in the container */
+ i = ao2_iterator_init(snapshot->channels, 0);
+ while ((channel_id_in_bridge = ao2_iterator_next(&i))) {
+ break;
+ }
+ ao2_iterator_destroy(&i);
+
+ if (ao2_primary) {
+ primary = ao2_primary;
+ } else {
+ primary = channel_id_in_bridge;
+ }
+
+ remove_bridge_primary(primary);
+ }
+ }
+}
+
static void save_dialstatus(struct ast_multi_channel_blob *blob)
{
ao2_link(cel_dialstatus_store, blob);
@@ -993,6 +1144,8 @@
ast_cli_unregister(&cli_status);
stasis_message_router_unsubscribe(cel_state_router);
cel_state_router = NULL;
+ ao2_cleanup(bridge_primaries);
+ bridge_primaries = NULL;
}
int ast_cel_engine_init(void)
@@ -1056,6 +1209,29 @@
return -1;
}
+ bridge_primaries = ao2_container_alloc(BRIDGE_PRIMARY_BUCKETS, bridge_assoc_hash, bridge_assoc_cmp);
+ if (!bridge_primaries) {
+ return -1;
+ }
+
+ ret |= stasis_message_router_add(cel_state_router,
+ ast_channel_entered_bridge_type(),
+ cel_bridge_enter_cb,
+ NULL);
+
+ ret |= stasis_message_router_add(cel_state_router,
+ ast_channel_left_bridge_type(),
+ cel_bridge_leave_cb,
+ NULL);
+
+ /* If somehow we failed to add any routes, just shut down the whole
+ * thing and fail it.
+ */
+ if (ret) {
+ ast_cel_engine_term();
+ return -1;
+ }
+
ast_register_atexit(ast_cel_engine_term);
return 0;
Modified: team/kmoore/bridge_construction-cel_channels/main/stasis_bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_channels/main/stasis_bridging.c?view=diff&rev=389327&r1=389326&r2=389327
==============================================================================
--- team/kmoore/bridge_construction-cel_channels/main/stasis_bridging.c (original)
+++ team/kmoore/bridge_construction-cel_channels/main/stasis_bridging.c Mon May 20 15:47:36 2013
@@ -94,6 +94,7 @@
ast_string_field_set(snapshot, technology, bridge->technology->name);
snapshot->feature_flags = bridge->feature_flags;
+ snapshot->capabilities = bridge->technology->capabilities;
snapshot->num_channels = bridge->num_channels;
snapshot->num_active = bridge->num_active;
Modified: team/kmoore/bridge_construction-cel_channels/main/stasis_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/bridge_construction-cel_channels/main/stasis_channels.c?view=diff&rev=389327&r1=389326&r2=389327
==============================================================================
--- team/kmoore/bridge_construction-cel_channels/main/stasis_channels.c (original)
+++ team/kmoore/bridge_construction-cel_channels/main/stasis_channels.c Mon May 20 15:47:36 2013
@@ -103,7 +103,6 @@
struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *chan)
{
RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
- struct ast_channel *bridged;
snapshot = ao2_alloc(sizeof(*snapshot), channel_snapshot_dtor);
if (!snapshot || ast_string_field_init(snapshot, 1024)) {
@@ -127,17 +126,6 @@
ast_string_field_set(snapshot, context, ast_channel_context(chan));
ast_string_field_set(snapshot, exten, ast_channel_exten(chan));
- bridged = ast_bridged_channel(chan);
- if (bridged) {
- ast_channel_ref(bridged);
- ast_channel_lock(bridged);
- ast_string_field_set(snapshot, bridged_name, ast_channel_name(bridged));
- ast_string_field_set(snapshot, bridged_id, ast_channel_uniqueid(bridged));
- ast_channel_unlock(bridged);
- ast_channel_unref(bridged);
- bridged = NULL;
- }
-
ast_string_field_set(snapshot, caller_name,
S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, ""));
ast_string_field_set(snapshot, caller_number,
@@ -164,6 +152,28 @@
snapshot->caller_pres = ast_party_id_presentation(&ast_channel_caller(chan)->id);
snapshot->manager_vars = ast_channel_get_manager_vars(chan);
+
+ ao2_ref(snapshot, +1);
+ return snapshot;
+}
+
+struct ast_channel_snapshot *ast_channel_snapshot_get_latest(
+ const char *uniqueid)
+{
+ RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+ struct ast_channel_snapshot *snapshot;
+
+ msg = stasis_cache_get(ast_channel_topic_all_cached(),
+ ast_channel_snapshot_type(), uniqueid);
+
+ if (!msg) {
+ return NULL;
+ }
+
+ snapshot = stasis_message_data(msg);
+ if (!snapshot) {
+ return NULL;
+ }
ao2_ref(snapshot, +1);
return snapshot;
More information about the asterisk-commits
mailing list