Exemplo n.º 1
0
void cc_queue_rmv_call( struct cc_data *data, struct cc_call *call)
{
	LM_DBG(" QUEUE - removing call %p \n",call);
	if ( !is_call_in_queue(data, call) ) { 
		LM_CRIT(" QUEUE - call not in queue l=%p, h=%p\n",
				call->lower_in_queue, call->higher_in_queue);
		abort();
	}

	if (call->lower_in_queue) {
		call->lower_in_queue->higher_in_queue =
			call->higher_in_queue;
	} else {
		data->queue.last = call->higher_in_queue;
	}
	if (call->higher_in_queue) {
		call->higher_in_queue->lower_in_queue =
			call->lower_in_queue;
	} else {
		data->queue.first = call->lower_in_queue;
	}
	call->lower_in_queue = call->higher_in_queue = NULL;
	data->queue.calls_no--;
	update_stat( call->flow->st_queued_calls, -1 );
}
Exemplo n.º 2
0
void cc_queue_push_call(struct cc_data *data, struct cc_call *call, int top)
{
	struct cc_call *call_it;
	int n = 0;

	LM_DBG(" QUEUE - adding call %p \n",call);
	if ( is_call_in_queue(data, call) ) {
		LM_CRIT(" QUEUE - call already in queue \n");
		abort();
	}

	if (top) {
		/* add the call in the very top of the queue */
		call_it = NULL;
	} else {
		/* search (priority based) the place in queue */
		for(call_it=data->queue.last ; call_it ; call_it=call_it->higher_in_queue){
			if (call_it->flow->priority <= call->flow->priority)
				break;
			n++;
		}
	}


	if (call_it) {
		/* add before it */
		if (call_it->lower_in_queue) {
			call_it->lower_in_queue->higher_in_queue = call;
		} else {
			data->queue.last = call;
		}
		call->lower_in_queue = call_it->lower_in_queue;
		call->higher_in_queue = call_it;
		call_it->lower_in_queue = call;
	} else {
		/* add in top of the queue */
		call->lower_in_queue = data->queue.first;
		if (data->queue.first) {
			data->queue.first->higher_in_queue = call;
		}
		else {
			data->queue.last = call;
		}
		call->higher_in_queue = NULL;
		data->queue.first = call;
	}
	data->queue.calls_no++;
	update_stat( call->flow->st_queued_calls, +1 );
	
	LM_DBG("adding call on pos %d (already %d calls), l=%p h=%p\n",
		n, data->queue.calls_no,
		call->lower_in_queue, call->higher_in_queue);
	call->ref_cnt++;

	if (call->queue_start==0)
		call->queue_start = get_ticks();
}
Exemplo n.º 3
0
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);
}