struct cc_call *cc_queue_pop_call_for_agent(struct cc_data *data, struct cc_agent *agent) { struct cc_call *call_it; unsigned int i; /* interate all the queued calls and see * * if they mathe the agent (as skills)*/ for(call_it=data->queue.first ; call_it ; call_it=call_it->lower_in_queue){ /* check the call skill against the agent skills */ for(i=0 ; i<agent->no_skills ; i++) { /* before taking a call out, be sure that call is fully initialized * from b2bua point of view (to avoid races) -> check the b2bua id */ if (call_it->b2bua_id.len!=0 && call_it->flow->skill==agent->skills[i]) { LM_DBG("found call %p for agent %p(%.*s) with skill %d \n", call_it, agent, agent->id.len, agent->id.s, call_it->flow->skill); /* remove the call from queue */ cc_queue_rmv_call( data, call_it); return call_it; } } } return NULL; }
static void terminate_call(struct cc_call *call, b2bl_dlg_stat_t* stat, call_state prev_state) { str un, fid, aid; int type; if(prev_state == CC_CALL_ENDED) { LM_CRIT("BUG - terminate state \n"); return; } LM_DBG("terminating call %p (stat=%p)\n",call,stat); lock_get( data->lock ); prepare_cdr( call, &un, &fid , &aid); if (prev_state==CC_CALL_TOAGENT) { /* free the agent */ if (stat && stat->call_time && prev_state==CC_CALL_TOAGENT) { call->agent->state = CC_AGENT_WRAPUP; call->agent->last_call_end = get_ticks(); call->flow->processed_calls ++; call->flow->avg_call_duration = ( ((float)stat->call_time + ((float)call->flow->avg_call_duration * (call->flow->processed_calls-1)) ) ) / call->flow->processed_calls ; /* update awt for established calls */ update_awt( stat->start_time - call->recv_time ); update_cc_flow_awt(call->flow, stat->start_time - call->recv_time); update_cc_agent_att(call->agent, stat->call_time); } else { call->agent->state = CC_AGENT_FREE; /* update awt for failed calls */ update_awt( get_ticks() - call->recv_time ); update_cc_flow_awt( call->flow, get_ticks() - call->recv_time ); } /* update last_call_end for agent */ cc_db_update_agent_end_call(call->agent); call->agent->ref_cnt--; call->agent = NULL; } else { /* update awt for failed calls */ update_awt( get_ticks() - call->recv_time ); update_cc_flow_awt( call->flow, get_ticks() - call->recv_time ); } /* remove the call from queue (if there) */ if ( is_call_in_queue(data, call) ) { cc_queue_rmv_call( data, call); call->ref_cnt--; } call->flow->ongoing_calls--; lock_release( data->lock ); if (call->setup_time==-1 && stat) call->setup_time = stat->setup_time; /* generate CDR */ type = (stat==NULL) ? -1 : ((prev_state==CC_CALL_TOAGENT && stat->call_time)? 0 : 1); cc_write_cdr( &un, &fid, &aid, type, call->recv_time, ((type==0)? stat->start_time : get_ticks()) - call->recv_time , (type==0)?stat->call_time:0 , call->setup_time, call->no_rejections, call->fst_flags, call->id); cc_db_delete_call(call); }