Index: channels/chan_agent.c =================================================================== --- channels/chan_agent.c (revision 34522) +++ channels/chan_agent.c (working copy) @@ -185,6 +185,10 @@ int wrapuptime; /*!< Wrapup time in ms */ ast_group_t group; /*!< Group memberships */ int acknowledged; /*!< Acknowledged */ + int transferring; /*!< Transferring call + Ideally should be reset on unsuccessful transfer attempt + */ + char moh[80]; /*!< Which music on hold */ char agent[AST_MAX_AGENT]; /*!< Agent ID */ char password[AST_MAX_AGENT]; /*!< Password for Agent login */ @@ -323,7 +327,7 @@ break; } if (!p) { - // Build the agent. + /* Build the agent. */ if (!(p = ast_calloc(1, sizeof(*p)))) return NULL; ast_copy_string(p->agent, agt, sizeof(p->agent)); @@ -434,6 +438,10 @@ struct ast_frame *f = NULL; static struct ast_frame answer_frame = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; const char *status; + + /*This variable to indicate that an Unpause is needed (avoid deadlock with ast_mutex_lock */ + int doPauseAfterUnlock = 0; + ast_mutex_lock(&p->lock); CHECK_FORMATS(ast, p); if (p->chan) { @@ -490,7 +498,13 @@ } break; case AST_FRAME_DTMF: - if (!p->acknowledged && (f->subclass == '#')) { + /* This is while waiting for acknowledgemt (after beep) +*/ + + if(p->acknowledged && (f->subclass == '#')) { + /* We should ignore zeroes for pause */ + p->transferring=1; + } else if (!p->acknowledged && (f->subclass == '#')) { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "%s acknowledged\n", p->chan->name); p->acknowledged = 1; @@ -500,7 +514,18 @@ /* terminates call */ ast_frfree(f); f = NULL; - } + } else if (f-> subclass == '0' ) { + + if(p->transferring) { + /*Don't pause member if a zero is entered + while transferring the call. */ + + } else { + /*Pause the agent.*/ + /*Set a flag to wait until the channel is unlocked for execution. */ + doPauseAfterUnlock = 1; + } + } break; case AST_FRAME_VOICE: /* don't pass voice until the call is acknowledged */ @@ -521,6 +546,13 @@ } } ast_mutex_unlock(&p->lock); + /* wait until after unlock to avoid deadlocks. */ + if(doPauseAfterUnlock) { + doPauseAfterUnlock=0; + char data[AST_MAX_AGENT+7]=""; + snprintf(data,AST_MAX_AGENT+7,"|Agent/%s",p->agent); + pbx_exec(p->chan, pbx_findapp("PauseQueueMember"),data); + } if (recordagentcalls && f == &answer_frame) agent_start_monitoring(ast,0); return f; @@ -714,6 +746,9 @@ p->app_sleep_cond = 1; p->acknowledged = 0; + /*At the end of every call clear transferring indicator. */ + p->transferring = 0; + /* if they really are hung up then set start to 0 so the test * later if we're called on an already downed channel * doesn't cause an agent to be logged out like when @@ -847,9 +882,18 @@ res = -1; break; } - if (f->frametype == AST_FRAME_DTMF) - res = f->subclass; - else + if (f->frametype == AST_FRAME_DTMF){ + /*This is while no callers are waiting.*/ + res = f->subclass; + + if(res == '0') { + /*Unpause the member.*/ + char data[AST_MAX_AGENT+7]=""; + snprintf(data,AST_MAX_AGENT+7,"|Agent/%s",p->agent); + + pbx_exec(p->chan, pbx_findapp("UnpauseQueueMember"),data); + } + } else res = 0; ast_frfree(f); ast_mutex_lock(&p->lock); @@ -2044,11 +2088,13 @@ ast_mutex_lock(&p->lock); p->owning_app = pthread_self(); ast_mutex_unlock(&p->lock); - if (p->ackcall > 1) + /*Have to go agent_ack_sleep even when not acknowledging as must detect '0' to unpause member. */ + +// if (p->ackcall > 1) res = agent_ack_sleep(p); - else - res = ast_safe_sleep_conditional( chan, 1000, - agent_cont_sleep, p ); +// else +// res = ast_safe_sleep_conditional( chan, 1000, + // agent_cont_sleep, p ); ast_mutex_unlock( &p->app_lock ); if ((p->ackcall > 1) && (res == 1)) { AST_LIST_LOCK(&agents);