Index: channels/chan_agent.c =================================================================== --- channels/chan_agent.c (revision 91829) +++ channels/chan_agent.c (working copy) @@ -157,6 +157,8 @@ 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 */ @@ -303,7 +305,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)); @@ -414,6 +416,8 @@ struct ast_frame *f = NULL; static struct ast_frame answer_frame = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; const char *status; + int pauseafterunlock = 0; + ast_mutex_lock(&p->lock); CHECK_FORMATS(ast, p); if (p->chan) { @@ -476,7 +480,11 @@ } break; case AST_FRAME_DTMF_END: - 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 == '#')) { ast_verb(3, "%s acknowledged\n", p->chan->name); p->acknowledged = 1; ast_frfree(f); @@ -485,7 +493,14 @@ /* 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. */ + pauseafterunlock = 1; + } + } break; case AST_FRAME_VOICE: case AST_FRAME_VIDEO: @@ -509,8 +524,15 @@ } } ast_mutex_unlock(&p->lock); + /* wait until after unlock to avoid deadlocks. */ + if (pauseafterunlock) { + char data[AST_MAX_AGENT + 7]; + pauseafterunlock = 0; + snprintf(data, sizeof(data), ",Agent/%s", p->agent); + pbx_exec(p->chan, pbx_findapp("PauseQueueMember"), data); + } if (recordagentcalls && f == &answer_frame) - agent_start_monitoring(ast,0); + agent_start_monitoring(ast, 0); return f; } @@ -739,6 +761,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 @@ -838,6 +863,7 @@ return 0; } +#if 0 static int agent_cont_sleep( void *data ) { struct agent_pvt *p; @@ -858,6 +884,7 @@ return res; } +#endif static int agent_ack_sleep(void *data) { @@ -881,9 +908,18 @@ f = ast_read(p->chan); if (!f) return -1; - if (f->frametype == AST_FRAME_DTMF) + if (f->frametype == AST_FRAME_DTMF) { + /* This is while no callers are waiting. */ res = f->subclass; - else + if (res == '0') { + /* Unpause the member. */ + char data[AST_MAX_AGENT + 7]; + snprintf(data, sizeof(data), ",Agent/%s", p->agent); + + pbx_exec(p->chan, pbx_findapp("UnpauseQueueMember"), data); + } + res = f->subclass; + } else res = 0; ast_frfree(f); ast_mutex_lock(&p->lock); @@ -1989,10 +2025,8 @@ ast_mutex_lock(&p->lock); p->owning_app = pthread_self(); ast_mutex_unlock(&p->lock); - if (p->ackcall > 1) - res = agent_ack_sleep(p); - else - res = ast_safe_sleep_conditional( chan, 1000, agent_cont_sleep, p ); + /* Have to agent_ack_sleep even when not acknowledging, as we must detect '0' to unpause member. */ + res = agent_ack_sleep(p); ast_mutex_unlock( &p->app_lock ); if ((p->ackcall > 1) && (res == 1)) { AST_LIST_LOCK(&agents);