[asterisk-commits] eliel: branch group/data_api_gsoc2009 r198247 - in /team/group/data_api_gsoc2...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri May 29 20:41:01 CDT 2009
Author: eliel
Date: Fri May 29 20:40:53 2009
New Revision: 198247
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=198247
Log:
Merged revisions 198088,198139,198146,198182-198183,198186,198217 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk
........
r198088 | jpeeler | 2009-05-29 15:19:51 -0400 (Fri, 29 May 2009) | 9 lines
New signaling module to handle analog operations in chan_dahdi
This branch splits all the analog signaling logic out of chan_dahdi.c into
sig_analog.c. Functionality in theory should not change at all. As noted
in the code, there is still some unused code remaining that will be cleaned
up in a later commit.
Review: https://reviewboard.asterisk.org/r/253/
........
r198139 | eliel | 2009-05-29 15:46:07 -0400 (Fri, 29 May 2009) | 15 lines
Simplify the Makefile and avoid needing to specify each object file.
Instead of specifying every object file, use make's magic to generate
it.
This will generate less conflicts in team branches when a new file is
added in trunk.
(closes issue #15226)
Reported by: eliel
Patches:
makefile uploaded by eliel (license 64)
Review: http://reviewboard.asterisk.org/r/269/
........
r198146 | russell | 2009-05-29 16:06:59 -0400 (Fri, 29 May 2009) | 38 lines
Resolve issues with choppy sound when using res_timing_pthread.
The situation that caused this problem was when continuous mode was being
turned on and off while a rate was set for a timing interface. A very easy
way to replicate this bug was to do a Playback() from behind a Local channel.
In this scenario, a rate gets set on the channel for doing file playback.
At the same time, continuous mode gets turned on and off about every 20 ms
as frames get queued on to the PBX side channel from the other side of the
Local channel.
Essentially, this module treated continuous mode and a set rate as mutually
exclusive states for the timer to be in. When I dug deep enough, I observed
the following pattern:
1) Set timer to tick every 20 ms.
2) Wait almost 20 ms ...
3) Continuous mode gets turned on for a queued up frame
4) Continuous mode gets turned off
5) The timer goes back to its tick per 20 ms. state but starts counting
at 0 ms.
6) Goto step 2.
Sometimes, res_timing_pthread would make it 20 ms and produce a timer tick,
but not most of the time. This is what produced the choppy sound (or sometimes
no sound at all).
Now, the module treats continuous mode and a set rate as completely independent
timer modes. They can be enabled and disabled independently of each other and
things work as expected.
(closes issue #14412)
Reported by: dome
Patches:
issue14412.diff.txt uploaded by russell (license 2)
issue14412-1.6.1.0.diff.txt uploaded by russell (license 2)
Tested by: DennisD, russell
........
r198182 | twilson | 2009-05-29 18:21:42 -0400 (Fri, 29 May 2009) | 2 lines
Add a couple of TODO items so I don't forget
........
r198183 | russell | 2009-05-29 18:33:31 -0400 (Fri, 29 May 2009) | 2 lines
Improve handling of trying to ACK too many timer expirations.
........
r198186 | russell | 2009-05-29 19:04:31 -0400 (Fri, 29 May 2009) | 2 lines
Suggesting that only a single timing module be loaded is no longer necessary.
........
r198217 | eliel | 2009-05-29 21:04:57 -0400 (Fri, 29 May 2009) | 10 lines
Remove not used code in the Agent channel.
This code was there because of the AgentCallbackLogin() application.
->loginchan[] member was only used by AgentCallbackLogin().
Agent where dumped to astdb if they where logged in using AgentCallbacklogin()
so they are not being dumper anymore.
Review: https://reviewboard.asterisk.org/r/267/
........
Modified:
team/group/data_api_gsoc2009/ (props changed)
team/group/data_api_gsoc2009/channels/Makefile
team/group/data_api_gsoc2009/channels/chan_agent.c
team/group/data_api_gsoc2009/channels/chan_dahdi.c
team/group/data_api_gsoc2009/configs/agents.conf.sample
team/group/data_api_gsoc2009/configs/modules.conf.sample
team/group/data_api_gsoc2009/main/Makefile
team/group/data_api_gsoc2009/res/res_calendar.c
team/group/data_api_gsoc2009/res/res_timing_pthread.c
Propchange: team/group/data_api_gsoc2009/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri May 29 20:40:53 2009
@@ -1,1 +1,1 @@
-/trunk:1-198086
+/trunk:1-198235
Modified: team/group/data_api_gsoc2009/channels/Makefile
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/data_api_gsoc2009/channels/Makefile?view=diff&rev=198247&r1=198246&r2=198247
==============================================================================
--- team/group/data_api_gsoc2009/channels/Makefile (original)
+++ team/group/data_api_gsoc2009/channels/Makefile Fri May 29 20:40:53 2009
@@ -69,6 +69,7 @@
rm -f h323/Makefile
$(if $(filter chan_iax2,$(EMBEDDED_MODS)),modules.link,chan_iax2.so): iax2-parser.o iax2-provision.o
+$(if $(filter chan_dahdi,$(EMBEDDED_MODS)),modules.link,chan_dahdi.so): sig_analog.o
ifneq ($(filter chan_h323,$(EMBEDDED_MODS)),)
modules.link: h323/libchanh323.a
Modified: team/group/data_api_gsoc2009/channels/chan_agent.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/data_api_gsoc2009/channels/chan_agent.c?view=diff&rev=198247&r1=198246&r2=198247
==============================================================================
--- team/group/data_api_gsoc2009/channels/chan_agent.c (original)
+++ team/group/data_api_gsoc2009/channels/chan_agent.c Fri May 29 20:40:53 2009
@@ -212,9 +212,6 @@
static const char pa_family[] = "Agents"; /*!< Persistent Agents astdb family */
#define PA_MAX_LEN 2048 /*!< The maximum length of each persistent member agent database entry */
-static int persistent_agents = 0; /*!< queues.conf [general] option */
-static void dump_agents(void);
-
#define DEFAULT_ACCEPTDTMF '#'
#define DEFAULT_ENDDTMF '*'
@@ -275,7 +272,6 @@
ast_cond_t app_complete_cond;
volatile int app_sleep_cond; /**< Sleep condition for the login app */
struct ast_channel *owner; /**< Agent */
- char loginchan[80]; /**< channel they logged in from */
char logincallerid[80]; /**< Caller ID they had when they logged in */
struct ast_channel *chan; /**< Channel we use */
unsigned int flags; /**< Flags show if settings were applied with channel vars */
@@ -319,7 +315,6 @@
/*--- Forward declarations */
static struct ast_channel *agent_request(const char *type, int format, void *data, int *cause);
static int agent_devicestate(void *data);
-static void agent_logoff_maintenance(struct agent_pvt *p, char *loginchan, long logintime, const char *uniqueid, char *logcommand);
static int agent_digit_begin(struct ast_channel *ast, char digit);
static int agent_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int agent_call(struct ast_channel *ast, char *dest, int timeout);
@@ -332,7 +327,6 @@
static int agent_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
static int agent_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static struct ast_channel *agent_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
-static void set_agentbycallerid(const char *callerid, const char *agent);
static char *complete_agent_logoff_cmd(const char *line, const char *word, int pos, int state);
static struct ast_channel* agent_get_base_channel(struct ast_channel *chan);
static int agent_set_base_channel(struct ast_channel *chan, struct ast_channel *base);
@@ -539,7 +533,6 @@
struct agent_pvt *p = ast->tech_pvt;
struct ast_frame *f = NULL;
static struct ast_frame answer_frame = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
- const char *status;
int cur_time = time(NULL);
ast_mutex_lock(&p->lock);
CHECK_FORMATS(ast, p);
@@ -553,33 +546,9 @@
} else
f = &ast_null_frame;
if (!f) {
- /* If there's a channel, hang it up (if it's on a callback) make it NULL */
+ /* If there's a channel, make it NULL */
if (p->chan) {
p->chan->_bridge = NULL;
- /* Note that we don't hangup if it's not a callback because Asterisk will do it
- for us when the PBX instance that called login finishes */
- if (!ast_strlen_zero(p->loginchan)) {
- if (p->chan)
- ast_debug(1, "Bridge on '%s' being cleared (2)\n", p->chan->name);
- if (p->owner->_state != AST_STATE_UP) {
- int howlong = cur_time - p->start;
- if (p->autologoff && howlong >= p->autologoff) {
- p->loginstart = 0;
- ast_log(LOG_NOTICE, "Agent '%s' didn't answer/confirm within %d seconds (waited %d)\n", p->name, p->autologoff, howlong);
- agent_logoff_maintenance(p, p->loginchan, (cur_time = p->loginstart), ast->uniqueid, "Autologoff");
- }
- }
- status = pbx_builtin_getvar_helper(p->chan, "CHANLOCALSTATUS");
- if (autologoffunavail && status && !strcasecmp(status, "CHANUNAVAIL")) {
- long logintime = cur_time - p->loginstart;
- p->loginstart = 0;
- ast_log(LOG_NOTICE, "Agent read: '%s' is not available now, auto logoff\n", p->name);
- agent_logoff_maintenance(p, p->loginchan, logintime, ast->uniqueid, "Chanunavail");
- }
- ast_hangup(p->chan);
- if (p->wrapuptime && p->acknowledged)
- p->lastdisc = ast_tvadd(ast_tvnow(), ast_samp2tv(p->wrapuptime, 1000));
- }
p->chan = NULL;
ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
p->acknowledged = 0;
@@ -595,7 +564,6 @@
int howlong = cur_time - p->start;
if (p->autologoff && (howlong >= p->autologoff)) {
ast_log(LOG_NOTICE, "Agent '%s' didn't answer/confirm within %d seconds (waited %d)\n", p->name, p->autologoff, howlong);
- agent_logoff_maintenance(p, p->loginchan, (cur_time - p->loginstart), ast->uniqueid, "Autologoff");
agent_logoff(p->agent, 0);
}
}
@@ -784,16 +752,6 @@
if (newstate)
ast_setstate(ast, newstate);
return res;
- } else if (!ast_strlen_zero(p->loginchan)) {
- time(&p->start);
- /* Call on this agent */
- ast_verb(3, "outgoing agentcall, to agent '%s', on '%s'\n", p->agent, p->chan->name);
- ast_channel_set_connected_line(p->chan, &ast->connected);
- ast_channel_inherit_variables(ast, p->chan);
- res = ast_call(p->chan, p->loginchan, 0);
- CLEANUP(ast,p);
- ast_mutex_unlock(&p->lock);
- return res;
}
ast_verb(3, "agent_call, call to agent '%s' call on '%s'\n", p->agent, p->chan->name);
ast_debug(3, "Playing beep, lang '%s'\n", p->chan->language);
@@ -822,9 +780,9 @@
}
if(!res) {
/* Call is immediately up, or might need ack */
- if (p->ackcall > 1)
+ if (p->ackcall) {
newstate = AST_STATE_RINGING;
- else {
+ } else {
newstate = AST_STATE_UP;
if (recordagentcalls)
agent_start_monitoring(ast, 0);
@@ -839,19 +797,6 @@
return res;
}
-/*! \brief store/clear the global variable that stores agentid based on the callerid */
-static void set_agentbycallerid(const char *callerid, const char *agent)
-{
- char buf[AST_MAX_BUF];
-
- /* if there is no Caller ID, nothing to do */
- if (ast_strlen_zero(callerid))
- return;
-
- snprintf(buf, sizeof(buf), "%s_%s", GETAGENTBYCALLERID, callerid);
- pbx_builtin_setvar_helper(NULL, buf, agent);
-}
-
/*! \brief return the channel or base channel if one exists. This function assumes the channel it is called on is already locked */
struct ast_channel* agent_get_base_channel(struct ast_channel *chan)
{
@@ -890,7 +835,7 @@
{
struct agent_pvt *p = ast->tech_pvt;
int howlong = 0;
- const char *status;
+
ast_mutex_lock(&p->lock);
p->owner = NULL;
ast->tech_pvt = NULL;
@@ -915,37 +860,7 @@
if (p->chan) {
p->chan->_bridge = NULL;
/* If they're dead, go ahead and hang up on the agent now */
- if (!ast_strlen_zero(p->loginchan)) {
- /* Store last disconnect time */
- if (p->wrapuptime)
- p->lastdisc = ast_tvadd(ast_tvnow(), ast_samp2tv(p->wrapuptime, 1000));
- else
- p->lastdisc = ast_tv(0,0);
- if (p->chan) {
- status = pbx_builtin_getvar_helper(p->chan, "CHANLOCALSTATUS");
- if (autologoffunavail && status && !strcasecmp(status, "CHANUNAVAIL")) {
- long logintime = time(NULL) - p->loginstart;
- p->loginstart = 0;
- ast_log(LOG_NOTICE, "Agent hangup: '%s' is not available now, auto logoff\n", p->name);
- agent_logoff_maintenance(p, p->loginchan, logintime, ast->uniqueid, "Chanunavail");
- }
- /* Recognize the hangup and pass it along immediately */
- ast_hangup(p->chan);
- p->chan = NULL;
- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
- }
- ast_debug(1, "Hungup, howlong is %d, autologoff is %d\n", howlong, p->autologoff);
- if ((p->deferlogoff) || (howlong && p->autologoff && (howlong > p->autologoff))) {
- long logintime = time(NULL) - p->loginstart;
- p->loginstart = 0;
- if (!p->deferlogoff)
- ast_log(LOG_NOTICE, "Agent '%s' didn't answer/confirm within %d seconds (waited %d)\n", p->name, p->autologoff, howlong);
- p->deferlogoff = 0;
- agent_logoff_maintenance(p, p->loginchan, logintime, ast->uniqueid, "Autologoff");
- if (persistent_agents)
- dump_agents();
- }
- } else if (p->dead) {
+ if (p->dead) {
ast_channel_lock(p->chan);
ast_softhangup(p->chan, AST_SOFTHANGUP_EXPLICIT);
ast_channel_unlock(p->chan);
@@ -961,10 +876,7 @@
/* Only register a device state change if the agent is still logged in */
if (!p->loginstart) {
- p->loginchan[0] = '\0';
p->logincallerid[0] = '\0';
- if (persistent_agents)
- dump_agents();
} else {
ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
}
@@ -992,10 +904,8 @@
ast_mutex_unlock(&p->lock);
}
/* Release ownership of the agent to other threads (presumably running the login app). */
- if (ast_strlen_zero(p->loginchan)) {
- p->app_lock_flag = 0;
- ast_cond_signal(&p->app_complete_cond);
- }
+ p->app_lock_flag = 0;
+ ast_cond_signal(&p->app_complete_cond);
}
return 0;
}
@@ -1132,7 +1042,7 @@
alreadylocked = p->app_lock_flag;
p->app_lock_flag = 1;
- if(ast_strlen_zero(p->loginchan) && alreadylocked) {
+ if (alreadylocked) {
if (p->chan) {
ast_queue_frame(p->chan, &ast_null_frame);
ast_mutex_unlock(&p->lock); /* For other thread to read the condition. */
@@ -1149,18 +1059,6 @@
ast_cond_signal(&p->app_complete_cond);
return NULL;
}
- } else if (!ast_strlen_zero(p->loginchan)) {
- if (p->chan)
- ast_queue_frame(p->chan, &ast_null_frame);
- if (!p->chan) {
- ast_log(LOG_WARNING, "Agent disconnected while we were connecting the call\n");
- p->owner = NULL;
- tmp->tech_pvt = NULL;
- p->app_sleep_cond = 1;
- tmp = ast_channel_release(tmp);
- ast_mutex_unlock(&p->lock); /* For other thread to read the condition. */
- return NULL;
- }
}
if (p->chan)
ast_indicate(p->chan, AST_CONTROL_UNHOLD);
@@ -1179,7 +1077,6 @@
struct ast_config *ucfg;
struct ast_variable *v;
struct agent_pvt *p;
- const char *general_val;
const char *catname;
const char *hasagent;
int genhasagent;
@@ -1222,8 +1119,6 @@
savecallsin[0] = '\0';
/* Read in [general] section for persistence */
- if ((general_val = ast_variable_retrieve(cfg, "general", "persistentagents")))
- persistent_agents = ast_true(general_val);
multiplelogin = ast_true(ast_variable_retrieve(cfg, "general", "multiplelogin"));
/* Read in the [agents] section */
@@ -1239,12 +1134,9 @@
if (autologoff < 0)
autologoff = 0;
} else if (!strcasecmp(v->name, "ackcall")) {
- if (!strcasecmp(v->value, "always"))
- ackcall = 2;
- else if (ast_true(v->value))
+ if (ast_true(v->value) || !strcasecmp(v->value, "always")) {
ackcall = 1;
- else
- ackcall = 0;
+ }
} else if (!strcasecmp(v->name, "endcall")) {
endcall = ast_true(v->value);
} else if (!strcasecmp(v->name, "acceptdtmf")) {
@@ -1371,7 +1263,7 @@
if (needlock)
AST_LIST_UNLOCK(&agents);
if (parent && chan) {
- if (newlyavailable->ackcall > 1) {
+ if (newlyavailable->ackcall) {
/* Don't do beep here */
res = 0;
} else {
@@ -1469,8 +1361,7 @@
AST_LIST_LOCK(&agents);
AST_LIST_TRAVERSE(&agents, p, list) {
ast_mutex_lock(&p->lock);
- if (!p->pending && ((groupmatch && (p->group & groupmatch)) || !strcmp(data, p->agent)) &&
- ast_strlen_zero(p->loginchan)) {
+ if (!p->pending && ((groupmatch && (p->group & groupmatch)) || !strcmp(data, p->agent))) {
if (p->chan)
hasagent++;
now = ast_tvnow();
@@ -1493,23 +1384,16 @@
AST_LIST_TRAVERSE(&agents, p, list) {
ast_mutex_lock(&p->lock);
if (!p->pending && ((groupmatch && (p->group & groupmatch)) || !strcmp(data, p->agent))) {
- if (p->chan || !ast_strlen_zero(p->loginchan))
+ if (p->chan) {
hasagent++;
+ }
now = ast_tvnow();
-#if 0
- ast_log(LOG_NOTICE, "Time now: %ld, Time of lastdisc: %ld\n", now.tv_sec, p->lastdisc.tv_sec);
-#endif
if (!p->lastdisc.tv_sec || (now.tv_sec >= p->lastdisc.tv_sec)) {
p->lastdisc = ast_tv(0, 0);
/* Agent must be registered, but not have any active call, and not be in a waiting state */
if (!p->owner && p->chan) {
/* Could still get a fixed agent */
chan = agent_new(p, AST_STATE_DOWN);
- } else if (!p->owner && !ast_strlen_zero(p->loginchan)) {
- /* Adjustable agent */
- p->chan = ast_request("Local", format, p->loginchan, cause);
- if (p->chan)
- chan = agent_new(p, AST_STATE_DOWN);
}
if (chan) {
ast_mutex_unlock(&p->lock);
@@ -1562,7 +1446,6 @@
{
const char *id = astman_get_header(m,"ActionID");
char idText[256] = "";
- char chanbuf[256];
struct agent_pvt *p;
char *username = NULL;
char *loginChan = NULL;
@@ -1588,16 +1471,7 @@
/* Set a default status. It 'should' get changed. */
status = "AGENT_UNKNOWN";
- if (!ast_strlen_zero(p->loginchan) && !p->chan) {
- loginChan = p->loginchan;
- talkingto = "n/a";
- talkingtoChan = "n/a";
- status = "AGENT_IDLE";
- if (p->acknowledged) {
- snprintf(chanbuf, sizeof(chanbuf), " %s (Confirmed)", p->loginchan);
- loginChan = chanbuf;
- }
- } else if (p->chan) {
+ if (p->chan) {
loginChan = ast_strdupa(p->chan->name);
if (p->owner && p->owner->_bridge) {
talkingto = p->chan->cid.cid_num;
@@ -1638,49 +1512,9 @@
return 0;
}
-static void agent_logoff_maintenance(struct agent_pvt *p, char *loginchan, long logintime, const char *uniqueid, char *logcommand)
-{
- char *tmp = NULL;
- char agent[AST_MAX_AGENT];
-
- if (!ast_strlen_zero(logcommand))
- tmp = logcommand;
- else
- tmp = ast_strdupa("");
-
- snprintf(agent, sizeof(agent), "Agent/%s", p->agent);
-
- if (!ast_strlen_zero(uniqueid)) {
- manager_event(EVENT_FLAG_AGENT, "Agentcallbacklogoff",
- "Agent: %s\r\n"
- "Reason: %s\r\n"
- "Loginchan: %s\r\n"
- "Logintime: %ld\r\n"
- "Uniqueid: %s\r\n",
- p->agent, tmp, loginchan, logintime, uniqueid);
- } else {
- manager_event(EVENT_FLAG_AGENT, "Agentcallbacklogoff",
- "Agent: %s\r\n"
- "Reason: %s\r\n"
- "Loginchan: %s\r\n"
- "Logintime: %ld\r\n",
- p->agent, tmp, loginchan, logintime);
- }
-
- ast_queue_log("NONE", ast_strlen_zero(uniqueid) ? "NONE" : uniqueid, agent, "AGENTCALLBACKLOGOFF", "%s|%ld|%s", loginchan, logintime, tmp);
- set_agentbycallerid(p->logincallerid, NULL);
- p->loginchan[0] ='\0';
- p->logincallerid[0] = '\0';
- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "Agent/%s", p->agent);
- if (persistent_agents)
- dump_agents();
-
-}
-
static int agent_logoff(const char *agent, int soft)
{
struct agent_pvt *p;
- long logintime;
int ret = -1; /* Return -1 if no agent if found */
AST_LIST_LOCK(&agents);
@@ -1710,10 +1544,6 @@
ast_mutex_unlock(&p->lock);
} else
p->deferlogoff = 1;
- } else {
- logintime = time(NULL) - p->loginstart;
- p->loginstart = 0;
- agent_logoff_maintenance(p, p->loginchan, logintime, NULL, "CommandLogoff");
}
break;
}
@@ -1855,15 +1685,6 @@
else
strcpy(talkingto, " is idle");
online_agents++;
- } else if (!ast_strlen_zero(p->loginchan)) {
- if (ast_tvdiff_ms(ast_tvnow(), p->lastdisc) > 0 || !(p->lastdisc.tv_sec))
- snprintf(location, sizeof(location) - 20, "available at '%s'", p->loginchan);
- else
- snprintf(location, sizeof(location) - 20, "wrapping up at '%s'", p->loginchan);
- talkingto[0] = '\0';
- online_agents++;
- if (p->acknowledged)
- strncat(location, " (Confirmed)", sizeof(location) - strlen(location) - 1);
} else {
strcpy(location, "not logged in");
talkingto[0] = '\0';
@@ -1929,13 +1750,6 @@
strcpy(talkingto, " is idle");
agent_status = 1;
online_agents++;
- } else if (!ast_strlen_zero(p->loginchan)) {
- snprintf(location, sizeof(location) - 20, "available at '%s'", p->loginchan);
- talkingto[0] = '\0';
- agent_status = 1;
- online_agents++;
- if (p->acknowledged)
- strncat(location, " (Confirmed)", sizeof(location) - strlen(location) - 1);
}
if (!ast_strlen_zero(p->moh))
snprintf(music, sizeof(music), " (musiconhold is '%s')", p->moh);
@@ -2083,12 +1897,11 @@
/* Set Channel Specific Agent Overrides */
if (!ast_strlen_zero(pbx_builtin_getvar_helper(chan, "AGENTACKCALL"))) {
- if (!strcasecmp(pbx_builtin_getvar_helper(chan, "AGENTACKCALL"), "always"))
- p->ackcall = 2;
- else if (ast_true(pbx_builtin_getvar_helper(chan, "AGENTACKCALL")))
+ if (ast_true(pbx_builtin_getvar_helper(chan, "AGENTACKCALL"))) {
p->ackcall = 1;
- else
+ } else {
p->ackcall = 0;
+ }
tmpoptions=pbx_builtin_getvar_helper(chan, "AGENTACKCALL");
ast_verb(3, "Saw variable AGENTACKCALL=%s, setting ackcall to: %d for Agent '%s'.\n", tmpoptions, p->ackcall, p->agent);
ast_set_flag(p, AGENT_FLAG_ACKCALL);
@@ -2134,7 +1947,6 @@
long logintime;
snprintf(agent, sizeof(agent), "Agent/%s", p->agent);
- p->loginchan[0] = '\0';
p->logincallerid[0] = '\0';
p->acknowledged = 0;
@@ -2177,10 +1989,11 @@
ast_getformatname(chan->readformat), ast_getformatname(chan->writeformat));
/* Login this channel and wait for it to go away */
p->chan = chan;
- if (p->ackcall > 1)
+ if (p->ackcall) {
check_beep(p, 0);
- else
+ } else {
check_availability(p, 0);
+ }
ast_mutex_unlock(&p->lock);
AST_LIST_UNLOCK(&agents);
ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
@@ -2205,10 +2018,11 @@
ast_debug(1, "Wrapup time for %s expired!\n", p->agent);
p->lastdisc = ast_tv(0, 0);
ast_devstate_changed(AST_DEVICE_NOT_INUSE, "Agent/%s", p->agent);
- if (p->ackcall > 1)
+ if (p->ackcall) {
check_beep(p, 0);
- else
+ } else {
check_availability(p, 0);
+ }
}
}
ast_mutex_unlock(&p->lock);
@@ -2221,11 +2035,12 @@
ast_mutex_unlock(&p->app_lock);
ast_mutex_lock(&p->lock);
ast_mutex_unlock(&p->lock);
- if (p->ackcall > 1)
+ if (p->ackcall) {
res = agent_ack_sleep(p);
- else
+ } else {
res = ast_safe_sleep_conditional( chan, 1000, agent_cont_sleep, p );
- if ((p->ackcall > 1) && (res == 1)) {
+ }
+ if (p->ackcall && (res == 1)) {
AST_LIST_LOCK(&agents);
ast_mutex_lock(&p->lock);
check_availability(p, 0);
@@ -2352,84 +2167,6 @@
return 0;
}
-/*!
- * \brief Dump AgentCallbackLogin agents to the ASTdb database for persistence
- */
-static void dump_agents(void)
-{
- struct agent_pvt *cur_agent = NULL;
- char buf[256];
-
- AST_LIST_TRAVERSE(&agents, cur_agent, list) {
- if (cur_agent->chan)
- continue;
-
- if (!ast_strlen_zero(cur_agent->loginchan)) {
- snprintf(buf, sizeof(buf), "%s;%s", cur_agent->loginchan, cur_agent->logincallerid);
- if (ast_db_put(pa_family, cur_agent->agent, buf))
- ast_log(LOG_WARNING, "failed to create persistent entry in ASTdb for %s!\n", buf);
- else
- ast_debug(1, "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);
- }
- }
-}
-
-/*!
- * \brief Reload the persistent agents from astdb.
- */
-static void reload_agents(void)
-{
- char *agent_num;
- struct ast_db_entry *db_tree;
- struct ast_db_entry *entry;
- struct agent_pvt *cur_agent;
- char agent_data[256];
- char *parse;
- char *agent_chan;
- char *agent_callerid;
-
- db_tree = ast_db_gettree(pa_family, NULL);
-
- AST_LIST_LOCK(&agents);
- for (entry = db_tree; entry; entry = entry->next) {
- agent_num = entry->key + strlen(pa_family) + 2;
- AST_LIST_TRAVERSE(&agents, cur_agent, list) {
- ast_mutex_lock(&cur_agent->lock);
- if (strcmp(agent_num, cur_agent->agent) == 0)
- break;
- ast_mutex_unlock(&cur_agent->lock);
- }
- if (!cur_agent) {
- ast_db_del(pa_family, agent_num);
- continue;
- } else
- ast_mutex_unlock(&cur_agent->lock);
- if (!ast_db_get(pa_family, agent_num, agent_data, sizeof(agent_data)-1)) {
- ast_debug(1, "Reload Agent from AstDB: %s on %s\n", cur_agent->agent, agent_data);
- parse = agent_data;
- agent_chan = strsep(&parse, ";");
- agent_callerid = strsep(&parse, ";");
- ast_copy_string(cur_agent->loginchan, agent_chan, sizeof(cur_agent->loginchan));
- if (agent_callerid) {
- ast_copy_string(cur_agent->logincallerid, agent_callerid, sizeof(cur_agent->logincallerid));
- set_agentbycallerid(cur_agent->logincallerid, cur_agent->agent);
- } else
- cur_agent->logincallerid[0] = '\0';
- if (cur_agent->loginstart == 0)
- time(&cur_agent->loginstart);
- ast_devstate_changed(AST_DEVICE_UNKNOWN, "Agent/%s", cur_agent->agent);
- }
- }
- AST_LIST_UNLOCK(&agents);
- if (db_tree) {
- ast_log(LOG_NOTICE, "Agents successfully reloaded from database.\n");
- ast_db_freetree(db_tree);
- }
-}
-
/*! \brief Part of PBX channel interface */
static int agent_devicestate(void *data)
{
@@ -2458,7 +2195,7 @@
} else {
if (res == AST_DEVICE_BUSY)
res = AST_DEVICE_INUSE;
- if (p->chan || !ast_strlen_zero(p->loginchan)) {
+ if (p->chan) {
if (res == AST_DEVICE_INVALID)
res = AST_DEVICE_UNKNOWN;
} else if (res == AST_DEVICE_INVALID)
@@ -2523,8 +2260,9 @@
if (!strcasecmp(args.item, "status")) {
char *status = "LOGGEDOUT";
- if (agent->chan || !ast_strlen_zero(agent->loginchan))
- status = "LOGGEDIN";
+ if (agent->chan) {
+ status = "LOGGEDIN";
+ }
ast_copy_string(buf, status, len);
} else if (!strcasecmp(args.item, "password"))
ast_copy_string(buf, agent->password, len);
@@ -2539,8 +2277,9 @@
if (tmp)
*tmp = '\0';
}
- } else if (!strcasecmp(args.item, "exten"))
- ast_copy_string(buf, agent->loginchan, len);
+ } else if (!strcasecmp(args.item, "exten")) {
+ buf[0] = '\0';
+ }
AST_LIST_UNLOCK(&agents);
@@ -2570,8 +2309,6 @@
/* Read in the config */
if (!read_agent_config(0))
return AST_MODULE_LOAD_DECLINE;
- if (persistent_agents)
- reload_agents();
/* Dialplan applications */
ast_register_application_xml(app, login_exec);
ast_register_application_xml(app3, agentmonitoroutgoing_exec);
@@ -2591,11 +2328,7 @@
static int reload(void)
{
- if (!read_agent_config(1)) {
- if (persistent_agents)
- reload_agents();
- }
- return 0;
+ return read_agent_config(1);
}
static int unload_module(void)
Modified: team/group/data_api_gsoc2009/channels/chan_dahdi.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/data_api_gsoc2009/channels/chan_dahdi.c?view=diff&rev=198247&r1=198246&r2=198247
==============================================================================
--- team/group/data_api_gsoc2009/channels/chan_dahdi.c (original)
+++ team/group/data_api_gsoc2009/channels/chan_dahdi.c Fri May 29 20:40:53 2009
@@ -62,6 +62,7 @@
#include <dahdi/user.h>
#include <dahdi/tonezone.h>
+#include "sig_analog.h"
#ifdef HAVE_PRI
#include <libpri.h>
@@ -468,6 +469,8 @@
static int dahdi_sendtext(struct ast_channel *c, const char *text);
+static int analog_lib_handles(int signalling, int radio, int oprmode);
+
static void mwi_event_cb(const struct ast_event *event, void *userdata)
{
/* This module does not handle MWI in an event-based manner. However, it
@@ -753,6 +756,7 @@
static struct dahdi_pvt {
ast_mutex_t lock;
+ struct callerid_state *cs;
struct ast_channel *owner; /*!< Our current active owner (if applicable) */
/*!< Up to three channels can be associated with this call */
@@ -1333,6 +1337,7 @@
char begindigit;
/*! \brief TRUE if confrence is muted. */
int muting;
+ void *sig_pvt;
} *iflist = NULL, *ifend = NULL;
/*! \brief Channel configuration from chan_dahdi.conf .
@@ -1527,6 +1532,911 @@
#else
#define GET_CHANNEL(p) ((p)->channel)
#endif
+
+static enum analog_sigtype dahdisig_to_analogsig(int sig)
+{
+ switch (sig) {
+ case SIG_FXOLS:
+ return ANALOG_SIG_FXOLS;
+ case SIG_FXOGS:
+ return ANALOG_SIG_FXOGS;
+ case SIG_FXOKS:
+ return ANALOG_SIG_FXOKS;
+ case SIG_FXSLS:
+ return ANALOG_SIG_FXSLS;
+ case SIG_FXSGS:
+ return ANALOG_SIG_FXSGS;
+ case SIG_FXSKS:
+ return ANALOG_SIG_FXSKS;
+ case SIG_EMWINK:
+ return ANALOG_SIG_EMWINK;
+ case SIG_EM:
+ return ANALOG_SIG_EM;
+ case SIG_EM_E1:
+ return ANALOG_SIG_EM_E1;
+ case SIG_FEATD:
+ return ANALOG_SIG_FEATD;
+ case SIG_FEATDMF:
+ return ANALOG_SIG_FEATDMF;
+ case SIG_E911:
+ return SIG_E911;
+ case SIG_FGC_CAMA:
+ return ANALOG_SIG_FGC_CAMA;
+ case SIG_FGC_CAMAMF:
+ return ANALOG_SIG_FGC_CAMAMF;
+ case SIG_FEATB:
+ return ANALOG_SIG_FEATB;
+ case SIG_SFWINK:
+ return ANALOG_SIG_SFWINK;
+ case SIG_SF:
+ return ANALOG_SIG_SF;
+ case SIG_SF_FEATD:
+ return ANALOG_SIG_SF_FEATD;
+ case SIG_SF_FEATDMF:
+ return ANALOG_SIG_SF_FEATDMF;
+ case SIG_FEATDMF_TA:
+ return ANALOG_SIG_FEATDMF_TA;
+ case SIG_SF_FEATB:
+ return ANALOG_SIG_FEATB;
+ default:
+ return -1;
+ }
+}
+
+
+static int analog_tone_to_dahditone(enum analog_tone tone)
+{
+ switch (tone) {
+ case ANALOG_TONE_RINGTONE:
+ return DAHDI_TONE_RINGTONE;
+ case ANALOG_TONE_STUTTER:
+ return DAHDI_TONE_STUTTER;
+ case ANALOG_TONE_CONGESTION:
+ return DAHDI_TONE_CONGESTION;
+ case ANALOG_TONE_DIALTONE:
+ return DAHDI_TONE_DIALTONE;
+ case ANALOG_TONE_DIALRECALL:
+ return DAHDI_TONE_DIALRECALL;
+ case ANALOG_TONE_INFO:
+ return DAHDI_TONE_INFO;
+ default:
+ return -1;
+ }
+}
+
+static int analogsub_to_dahdisub(enum analog_sub analogsub)
+{
+ int index;
+
+ switch (analogsub) {
+ case ANALOG_SUB_REAL:
+ index = SUB_REAL;
+ break;
+ case ANALOG_SUB_CALLWAIT:
+ index = SUB_CALLWAIT;
+ break;
+ case ANALOG_SUB_THREEWAY:
+ index = SUB_THREEWAY;
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unidentified sub!\n");
+ index = SUB_REAL;
+ }
+
+ return index;
+}
+
+static enum analog_event dahdievent_to_analogevent(int event);
+static int bump_gains(struct dahdi_pvt *p);
+static int dahdi_setlinear(int dfd, int linear);
+
+static int my_start_cid_detect(void *pvt, int cid_signalling)
+{
+ struct dahdi_pvt *p = pvt;
+ int index = SUB_REAL;
+ p->cs = callerid_new(cid_signalling);
+ if (!p->cs) {
+ ast_log(LOG_ERROR, "Unable to alloc callerid\n");
+ return -1;
+ }
+ bump_gains(p);
+ dahdi_setlinear(p->subs[index].dfd, 0);
+
+ return 0;
+}
+
+static int my_stop_cid_detect(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ int index = SUB_REAL;
+ if (p->cs)
+ callerid_free(p->cs);
+ dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
+ return 0;
+}
+
+static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_event *ev, size_t timeout)
+{
+ struct dahdi_pvt *p = pvt;
+ struct pollfd poller;
+ char *name, *num;
+ int index = SUB_REAL;
+ int res;
+ unsigned char buf[256];
+ int flags;
+
+ poller.fd = p->subs[SUB_REAL].dfd;
+ poller.events = POLLPRI | POLLIN;
+ poller.revents = 0;
+
+ res = poll(&poller, 1, timeout);
+
+ if (poller.revents & POLLPRI) {
+ *ev = dahdievent_to_analogevent(dahdi_get_event(p->subs[SUB_REAL].dfd));
+ return 1;
+ }
+
+ if (poller.revents & POLLIN) {
+ /*** NOTES ***/
+ /* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function
+ * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until
+ * either a timeout occurss or CID is detected (returns 0). returning 1 should be event received, and -1 should be fail
+ * and die */
+ res = read(p->subs[index].dfd, buf, sizeof(buf));
+ if (res < 0) {
+ if (errno != ELAST) {
+ ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
+ callerid_free(p->cs);
+ return -1;
+ }
+ }
+ res = callerid_feed(p->cs, buf, res, AST_LAW(p));
+ if (res < 0) {
+ ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (res == 1) {
+ callerid_get(p->cs, &name, &num, &flags);
+ if (name)
+ ast_copy_string(namebuf, name, ANALOG_MAX_CID);
+ if (num)
+ ast_copy_string(numbuf, num, ANALOG_MAX_CID);
+
+ ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags);
+ return 0;
+ }
+ }
+
+ *ev = ANALOG_EVENT_NONE;
+ return 1;
+}
+
+static int send_callerid(struct dahdi_pvt *p);
+
+static int my_stop_callwait(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ p->callwaitingrepeat = 0;
+ p->cidcwexpire = 0;
+
+ return 0;
+}
+
+static int save_conference(struct dahdi_pvt *p);
+
+static int my_callwait(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
+ if (p->cidspill) {
+ ast_log(LOG_WARNING, "Spill already exists?!?\n");
+ free(p->cidspill);
+ }
+ if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
+ return -1;
+ save_conference(p);
+ /* Silence */
+ memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
+ if (!p->callwaitrings && p->callwaitingcallerid) {
+ ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
+ p->callwaitcas = 1;
+ p->cidlen = 2400 + 680 + READ_SIZE * 4;
+ } else {
+ ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
+ p->callwaitcas = 0;
+ p->cidlen = 2400 + READ_SIZE * 4;
+ }
+ p->cidpos = 0;
+ send_callerid(p);
+
+ return 0;
+}
+
+static int my_send_callerid(void *pvt, int cwcid, struct ast_callerid *cid)
+{
+ struct dahdi_pvt *p = pvt;
+
+ ast_log(LOG_ERROR, "Starting cid spill\n");
+
+ if (p->cidspill) {
+ ast_log(LOG_WARNING, "cidspill already exists??\n");
+ free(p->cidspill);
+ }
+
+ if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
+ if (cwcid == 0) {
+ p->cidlen = ast_callerid_generate(p->cidspill, cid->cid_name, cid->cid_num, AST_LAW(p));
+ } else {
+ p->callwaitcas = 0;
+ p->cidcwexpire = 0;
+ p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, cid->cid_name, cid->cid_num, AST_LAW(p));
+ p->cidlen += READ_SIZE * 4;
+ }
+ p->cidpos = 0;
+ send_callerid(p);
+ }
+ return 0;
+}
+
+static int my_dsp_reset_and_flush_digits(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ if (p->dsp)
+ ast_dsp_digitreset(p->dsp);
+
+ return 0;
+}
+
+static int my_dsp_set_digitmode(void *pvt, enum analog_dsp_digitmode mode)
+{
+ struct dahdi_pvt *p = pvt;
+
+ if (p->channel == CHAN_PSEUDO)
+ ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n");
+
+ if (mode == ANALOG_DIGITMODE_DTMF) {
+ /* If we do hardware dtmf, no need for a DSP */
+ if (p->hardwaredtmf) {
+ if (p->dsp) {
+ ast_dsp_free(p->dsp);
+ p->dsp = NULL;
+ }
+ return 0;
+ }
+
+ if (!p->dsp) {
+ p->dsp = ast_dsp_new();
+ if (!p->dsp) {
+ ast_log(LOG_ERROR, "Unable to allocate DSP\n");
+ return -1;
+ }
+ }
+
+ ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
+ } else if (mode == ANALOG_DIGITMODE_MF) {
+ if (!p->dsp) {
+ p->dsp = ast_dsp_new();
+ if (!p->dsp) {
+ ast_log(LOG_ERROR, "Unable to allocate DSP\n");
+ return -1;
+ }
+ }
+ ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax);
+ }
+ return 0;
+}
+
+static int dahdi_wink(struct dahdi_pvt *p, int index);
+
+static int my_wink(void *pvt, enum analog_sub sub)
+{
+ struct dahdi_pvt *p = pvt;
+ int index = analogsub_to_dahdisub(sub);
+ if (index != SUB_REAL) {
+ ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n");
+ }
+ return dahdi_wink(p, index);
+}
+
+static void wakeup_sub(struct dahdi_pvt *p, int a, struct dahdi_pri *pri);
+
+static int reset_conf(struct dahdi_pvt *p);
+
+static inline int dahdi_confmute(struct dahdi_pvt *p, int muted);
+
+static void my_handle_dtmfup(void *pvt, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest)
+{
+ struct ast_frame *f = *dest;
+ struct dahdi_pvt *p = pvt;
+ int idx = analogsub_to_dahdisub(analog_index);
+
+ ast_debug(1, "DTMF digit: %c on %s\n", f->subclass, ast->name);
+
+ if (f->subclass == 'f') {
+ /* Fax tone -- Handle and return NULL */
+ if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
+ /* If faxbuffers are configured, use them for the fax transmission */
+ if (p->usefaxbuffers && !p->bufferoverrideinuse) {
+ struct dahdi_bufferinfo bi = {
+ .txbufpolicy = p->faxbuf_policy,
+ .bufsize = p->bufsize,
+ .numbufs = p->faxbuf_no
+ };
+ int res;
+
+ if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
+ ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast->name, strerror(errno));
+ } else {
+ p->bufferoverrideinuse = 1;
+ }
+ }
+ p->faxhandled = 1;
+ if (strcmp(ast->exten, "fax")) {
+ const char *target_context = S_OR(ast->macrocontext, ast->context);
+
+ /* We need to unlock 'ast' here because ast_exists_extension has the
+ * potential to start autoservice on the channel. Such action is prone
+ * to deadlock.
+ */
+ ast_mutex_unlock(&p->lock);
+ ast_channel_unlock(ast);
+ if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
+ ast_channel_lock(ast);
+ ast_mutex_lock(&p->lock);
+ ast_verb(3, "Redirecting %s to fax extension\n", ast->name);
+ /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
+ pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
+ if (ast_async_goto(ast, target_context, "fax", 1))
+ ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
+ } else {
+ ast_channel_lock(ast);
+ ast_mutex_lock(&p->lock);
+ ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
+ }
+ } else {
+ ast_debug(1, "Already in a fax extension, not redirecting\n");
+ }
+ } else {
+ ast_debug(1, "Fax already handled\n");
+ }
+ dahdi_confmute(p, 0);
+ p->subs[idx].f.frametype = AST_FRAME_NULL;
+ p->subs[idx].f.subclass = 0;
+ *dest = &p->subs[idx].f;
+ }
+}
+
+static void my_lock_private(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+
+ ast_mutex_lock(&p->lock);
+}
+
+static void my_unlock_private(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+
+ ast_mutex_unlock(&p->lock);
+}
+
+static void my_increase_ss_count(void)
+{
+ ast_mutex_lock(&ss_thread_lock);
+ ss_thread_count++;
+ ast_mutex_unlock(&ss_thread_lock);
+}
+
+static void my_decrease_ss_count(void)
+{
+ ast_mutex_lock(&ss_thread_lock);
+ ss_thread_count--;
+ ast_cond_signal(&ss_thread_complete);
+ ast_mutex_unlock(&ss_thread_lock);
+}
+
+static void my_all_subchannels_hungup(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ int res, law;
+
+ p->faxhandled = 0;
+ p->didtdd = 0;
+
+ if (p->dsp) {
+ ast_dsp_free(p->dsp);
+ p->dsp = NULL;
+ }
+
+ law = DAHDI_LAW_DEFAULT;
[... 3180 lines stripped ...]
More information about the asterisk-commits
mailing list