[asterisk-commits] mmichelson: branch mmichelson/agent_experiment r375351 - /team/mmichelson/age...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Oct 23 14:08:12 CDT 2012


Author: mmichelson
Date: Tue Oct 23 14:08:08 2012
New Revision: 375351

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=375351
Log:
Take care of bridge allocation.

With this, it may actually be possible to run
the AgentLogin application and not crash. The
problem is that there is no way to actually
log out or end the session.


Modified:
    team/mmichelson/agent_experiment/channels/chan_agent2.c

Modified: team/mmichelson/agent_experiment/channels/chan_agent2.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/agent_experiment/channels/chan_agent2.c?view=diff&rev=375351&r1=375350&r2=375351
==============================================================================
--- team/mmichelson/agent_experiment/channels/chan_agent2.c (original)
+++ team/mmichelson/agent_experiment/channels/chan_agent2.c Tue Oct 23 14:08:08 2012
@@ -26,8 +26,35 @@
 
 #define AGENT_BUCKETS 37
 
+struct agent_bridge {
+	const char *name;
+	struct ast_bridge *bridge;
+};
+
+static int agent_bridge_hash(const void *obj, int flags)
+{
+	const struct agent_bridge *bridge = obj;
+	const char *name = (flags & OBJ_KEY) ? obj : bridge->name;
+	return ast_str_case_hash(name);
+}
+
+static int agent_bridge_cmp(void *obj, void *arg, int flags)
+{
+	struct agent_bridge *bridge1 = obj;
+	struct agent_bridge *bridge2 = arg;
+	const char *name = (flags & OBJ_KEY) ? arg : bridge2->name;
+	return strcasecmp(bridge1->name, name) ? 0 : (CMP_MATCH | CMP_STOP);
+}
+
+static void agent_bridge_destroy(void *obj)
+{
+	struct agent_bridge *bridge = obj;
+	ast_bridge_destroy(bridge->bridge);
+}
+
 struct agent_config {
 	struct ao2_container *agents;
+	struct ao2_container *bridges;
 };
 
 struct agent_cfg {
@@ -105,7 +132,8 @@
 static void agent_config_destroy(void *obj)
 {
 	struct agent_config *config = obj;
-	ao2_ref(config->agents, -1);
+	ao2_cleanup(config->agents);
+	ao2_cleanup(config->bridges);
 }
 
 static void *agent_config_alloc(void)
@@ -120,6 +148,12 @@
 
 	config->agents = ao2_container_alloc(AGENT_BUCKETS, agent_cfg_hash, agent_cfg_cmp); 
 	if (!config->agents) {
+		ao2_ref(config, -1);
+		return NULL;
+	}
+
+	config->bridges = ao2_container_alloc(AGENT_BUCKETS, agent_bridge_hash, agent_bridge_cmp);
+	if (!config->bridges) {
 		ao2_ref(config, -1);
 		return NULL;
 	}
@@ -150,7 +184,7 @@
 	/*! The current state of the agent */
 	const struct agent_state *current_state;
 	/*! The bridge the agent waits in while logged in */
-	struct ast_bridge *bridge;
+	struct agent_bridge *bridge;
 	/*! The channel the agent logged in with */
 	struct ast_channel *channel;
 	/*! The original channel tech for the logged-in channel */
@@ -255,13 +289,13 @@
 
 static int enter_logged_in(struct agent *agent)
 {
-	return ast_bridge_impart(agent->bridge, agent->channel, NULL, NULL, 0);
+	return ast_bridge_impart(agent->bridge->bridge, agent->channel, NULL, NULL, 0);
 }
 
 static int exit_logged_in(struct agent *agent)
 {
 	ast_assert(agent->current_state->state == AGENT_LOGGED_IN);
-	return ast_bridge_depart(agent->bridge, agent->channel);
+	return ast_bridge_depart(agent->bridge->bridge, agent->channel);
 }
 
 static const struct agent_state LOGGED_IN = {
@@ -370,6 +404,7 @@
 	}
 
 	ao2_cleanup(agent->channel);
+	ao2_cleanup(agent->bridge);
 	ao2_cleanup(agent->cfg);
 }
 
@@ -379,6 +414,7 @@
 	RAII_VAR(struct agent_cfg *, cfg, config ? ao2_find(config->agents, id, OBJ_KEY) : NULL, ao2_cleanup);
 	RAII_VAR(struct agent *, agent, ao2_alloc(sizeof(*agent), agent_destroy), ao2_cleanup);
 	struct ast_channel_tech *copy;
+	struct agent_bridge *bridge;
 
 	if (!cfg || !agent) {
 		return NULL;
@@ -387,13 +423,33 @@
 	{
 		SCOPED_CHANNELLOCK(lock, chan);
 
+		bridge = ao2_find(config->bridges, cfg->bridge, OBJ_KEY);
+		if (!bridge) {
+			bridge = ao2_alloc(sizeof(*bridge), agent_bridge_destroy);
+		}
+
+		if (!bridge) {
+			return NULL;
+		}
+
+		bridge->name = cfg->bridge;
+		bridge->bridge = ast_bridge_new(AST_BRIDGE_CAPABILITY_MULTIMIX, 0);
+
+		if (!bridge->bridge) {
+			ao2_ref(bridge, -1);
+			return NULL;
+		}
+
 		copy = get_modified_channel_tech(chan);
 		if (!copy) {
+			ao2_ref(bridge, -1);
 			return NULL;
 		}
 
+		ao2_link(config->bridges, bridge);
 		agent->channel = ast_channel_ref(chan);
 		agent->saved_channel_tech = ast_channel_tech(agent->channel);
+		agent->bridge = bridge;
 		ast_channel_tech_set(agent->channel, copy);
 		ao2_ref(cfg, +1);
 		agent->cfg = cfg;




More information about the asterisk-commits mailing list