--- channels/chan_agent.c.backup Fri Dec 31 13:36:06 2004 +++ channels/chan_agent.c Fri Dec 31 13:59:33 2004 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -82,6 +83,14 @@ #define AST_MAX_AGENT 80 /* Agent ID or Password max length */ #define AST_MAX_BUF 256 +/* Persistent Agents astdb family */ +static const char *pa_family = "/Agents"; +/* The maximum lengh of each persistent member agent database entry */ +#define PA_MAX_LEN 2048 +/* queues.conf [general] option */ +static int persistent_agents = 0; +static void dump_agents(void); + static int capability = -1; static unsigned int group; @@ -796,6 +805,7 @@ struct ast_config *cfg; struct ast_variable *v; struct agent_pvt *p, *pl, *pn; + char *general_val; group = 0; autologoff = 0; wrapuptime = 0; @@ -820,6 +830,11 @@ urlprefix[0] = '\0'; savecallsin[0] = '\0'; + /* Read in [general] section for persistance */ + if ((general_val = ast_variable_retrieve(cfg, "general", "persistentagents"))) + persistent_agents = ast_true(general_val); + + /* Read in the [agents] section */ v = ast_variable_browse(cfg, "agents"); while(v) { /* Create the interface list */ @@ -1379,6 +1394,8 @@ if (!res) res = ast_safe_sleep(chan, 1000); ast_mutex_unlock(&p->lock); + if (persistent_agents) + dump_agents(); } else if (!res) { #ifdef HONOR_MUSIC_CLASS /* check if the moh class was changed with setmusiconhold */ @@ -1567,6 +1584,86 @@ return 0; } +/* Dump AgentCallbackLogin agents to the database for persistence + * (basically copied from dump_queue_members() in apps/app_queue.c) + */ + +static void dump_agents(void) +{ + struct agent_pvt *cur_agent = NULL; + cur_agent = agents; + while (cur_agent) { + if (cur_agent->chan != NULL) { + cur_agent = cur_agent->next; + continue; + } + if (!ast_strlen_zero(cur_agent->loginchan)) { + if (ast_db_put(pa_family, cur_agent->agent, cur_agent->loginchan)) { + ast_log(LOG_WARNING, "failed to create persistent entry!\n"); + } else { + if (option_debug) { + ast_log(LOG_DEBUG, "Saved Agent: %s on %s\n", + cur_agent->agent, cur_agent->loginchan); + } + } + } else { + /* Delete - no agent or there is an error */ + ast_db_del(pa_family, cur_agent->agent); + } + cur_agent = cur_agent->next; + } +} + +/* Reload the persistent agents from astdb */ +static void reload_agents(void) +{ + char *pa_agent_num; + struct ast_db_entry *pa_db_tree = NULL; + int pa_family_len = 0; + struct agent_pvt *cur_agent = NULL; + char agent_data[80]; + + pa_db_tree = ast_db_gettree(pa_family, NULL); + + pa_family_len = strlen(pa_family); + ast_mutex_lock(&agentlock); + while (pa_db_tree) { + pa_agent_num = pa_db_tree->key + pa_family_len + 2; + cur_agent = agents; + while (cur_agent) { + ast_mutex_lock(&cur_agent->lock); + + if (strcmp(pa_agent_num, cur_agent->agent) == 0) + break; + ast_mutex_unlock(&cur_agent->lock); + cur_agent = cur_agent->next; + } + if (!cur_agent) { + ast_db_del(pa_family, pa_agent_num); + pa_db_tree = pa_db_tree->next; + continue; + } else + ast_mutex_unlock(&cur_agent->lock); + if (!ast_db_get(pa_family, pa_agent_num, agent_data, 80)) { + if (option_debug) { + ast_log(LOG_DEBUG, "Reload Agent: %s on %s\n", + cur_agent->agent, agent_data); + } + strncpy(cur_agent->loginchan,agent_data,80); + if (cur_agent->loginstart == 0) + time(&cur_agent->loginstart); + ast_device_state_changed("Agent/%s", cur_agent->agent); + } + pa_db_tree = pa_db_tree->next; + } + ast_log(LOG_NOTICE, "Agents sucessfully reloaded from database.\n"); + ast_mutex_unlock(&agentlock); + if (pa_db_tree) { + ast_db_freetree(pa_db_tree); + pa_db_tree = NULL; + } +} + int load_module() { /* Make sure we can register our sip channel type */ @@ -1580,12 +1677,16 @@ ast_cli_register(&cli_show_agents); /* Read in the config */ read_agent_config(); + if (persistent_agents) + reload_agents(); return 0; } int reload() { read_agent_config(); + if (persistent_agents) + reload_agents(); return 0; }