[asterisk-commits] mmichelson: branch mmichelson/agent_experiment r372131 - /team/mmichelson/age...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Sep 3 14:12:23 CDT 2012
Author: mmichelson
Date: Mon Sep 3 14:12:19 2012
New Revision: 372131
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=372131
Log:
Change login operation.
Now instead of finding an agent to use, we allocate a new one
on login. This means that there is no longer a need for the
logged out state, so it has been removed.
I have this fear that RAII_VAR may be my hammer and I'm
seeing everything as nails right now...
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=372131&r1=372130&r2=372131
==============================================================================
--- team/mmichelson/agent_experiment/channels/chan_agent2.c (original)
+++ team/mmichelson/agent_experiment/channels/chan_agent2.c Mon Sep 3 14:12:19 2012
@@ -100,7 +100,7 @@
.types = ACO_TYPES(&agent_option),
};
-static AO2_GLOBAL_OBJ_STATIC(globals);
+static AO2_GLOBAL_OBJ_STATIC(config_handle);
static void agent_config_destroy(void *obj)
{
@@ -127,7 +127,7 @@
return config;
}
-CONFIG_INFO_STANDARD(cfg_info, globals, agent_config_alloc,
+CONFIG_INFO_STANDARD(cfg_info, config_handle, agent_config_alloc,
.files = ACO_FILES(&agent_conf),
);
@@ -136,7 +136,6 @@
const struct ast_channel *requestor, const char *addr, int *cause);
enum agent_states {
- AGENT_LOGGED_OUT,
AGENT_LOGGED_IN,
AGENT_RINGING,
AGENT_ON_CALL,
@@ -199,19 +198,6 @@
/*! Function called when agent exits the state */
agent_state_fn exit;
};
-
-static int enter_logged_out(struct agent *agent)
-{
- const struct ast_channel_tech *to_free;
- SCOPED_CHANNELLOCK(lock, agent->channel);
-
- to_free = ast_channel_tech(agent->channel);
- ast_channel_tech_set(agent->channel, agent->saved_channel_tech);
- ast_free((void *)to_free);
-
- agent->saved_channel_tech = NULL;
- return 0;
-}
static struct ast_channel_tech *get_modified_channel_tech(const struct ast_channel *chan)
{
@@ -267,30 +253,6 @@
return copy;
}
-static int exit_logged_out(struct agent *agent)
-{
- struct ast_channel_tech *copy;
- SCOPED_CHANNELLOCK(lock, agent->channel);
-
- copy = get_modified_channel_tech(agent->channel);
-
- if (!copy) {
- return -1;
- }
-
- agent->saved_channel_tech = ast_channel_tech(agent->channel);
- ast_channel_tech_set(agent->channel, copy);
-
- return 0;
-}
-
-static const struct agent_state LOGGED_OUT = {
- .name = "LOGGED_OUT",
- .state = AGENT_LOGGED_OUT,
- .enter = enter_logged_out,
- .exit = exit_logged_out,
-};
-
static int enter_logged_in(struct agent *agent)
{
return ast_bridge_impart(agent->bridge, agent->channel, NULL, NULL, 0);
@@ -393,28 +355,68 @@
ast_debug(1, "Agent %s (channel %s) is ringing\n", addr, ast_channel_name(agent->channel));
/* Everything seems good. Time to change the state to RINGING */
- change_agent_state(agent, &RINGING);
+ return change_agent_state(agent, &RINGING);
+}
+
+static void agent_destroy(void *obj)
+{
+ struct agent *agent = obj;
+ const struct ast_channel_tech *to_free;
+
+ if (agent->saved_channel_tech) {
+ to_free = ast_channel_tech(agent->channel);
+ ast_channel_tech_set(agent->channel, agent->saved_channel_tech);
+ ast_free((void *)to_free);
+ }
+
+ ao2_cleanup(agent->channel);
+ ao2_cleanup(agent->cfg);
+}
+
+static struct agent *alloc_agent(struct ast_channel *chan, const char *id)
+{
+ RAII_VAR(struct agent_config*, config, ao2_global_obj_ref(config_handle), ao2_cleanup);
+ 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;
+
+ if (!cfg || !agent) {
+ return NULL;
+ }
+
+ {
+ SCOPED_CHANNELLOCK(lock, chan);
+
+ copy = get_modified_channel_tech(chan);
+ if (!copy) {
+ return NULL;
+ }
+
+ agent->channel = ast_channel_ref(chan);
+ agent->saved_channel_tech = ast_channel_tech(agent->channel);
+ ast_channel_tech_set(agent->channel, copy);
+ ao2_ref(cfg, +1);
+ agent->cfg = cfg;
+ ao2_ref(agent, +1);
+ return agent;
+ }
}
static int login_exec(struct ast_channel *chan, const char *data)
{
- /* Need to find the corresponding agent. If the agent is in anything
- * other than the AGENT_LOGGED_OUT state, then this operation is invalid.
- */
- RAII_VAR(struct agent *, agent, find_agent(data), ao2_cleanup);
+ RAII_VAR(struct agent *, existing_agent, find_agent(data), ao2_cleanup);
+ RAII_VAR(struct agent *, agent, alloc_agent(chan, data), ao2_cleanup);
SCOPED_AO2LOCK(lock, agent);
+
+ if (existing_agent) {
+ ast_log(LOG_WARNING, "Attempting to log in already logged-in agent %s\n", data);
+ return -1;
+ }
if (!agent) {
ast_log(LOG_WARNING, "Invalid agent %s specified for AgentLogin\n", data);
return -1;
}
-
- if (agent->current_state->state != AGENT_LOGGED_OUT) {
- ast_log(LOG_WARNING, "Attempting to log in already logged-in agent %s\n", data);
- return -1;
- }
-
- agent->channel = ast_channel_ref(chan);
if (change_agent_state(agent, &LOGGED_IN)) {
ast_log(LOG_WARNING, "Problem attempting to log agent %s in\n", data);
More information about the asterisk-commits
mailing list