Пример #1
0
VoiceCallDlg::VoiceCallDlg(const Jid& jid, VoiceCaller* voiceCaller)
	: QDialog(0), jid_(jid), voiceCaller_(voiceCaller)
{
	setAttribute(Qt::WA_DeleteOnClose);
	ui_.setupUi(this);
	setModal(false);

	setWindowTitle(QString(tr("Voice Call (%1)")).arg(jid.full()));

	// Voice Caller signals
	connect(voiceCaller_,SIGNAL(accepted(const Jid&)),SLOT(accepted(const Jid&)));
	connect(voiceCaller_,SIGNAL(rejected(const Jid&)),SLOT(rejected(const Jid&)));
	connect(voiceCaller_,SIGNAL(in_progress(const Jid&)),SLOT(in_progress(const Jid&)));
	connect(voiceCaller_,SIGNAL(terminated(const Jid&)),SLOT(terminated(const Jid&)));

	// Buttons
	ui_.pb_hangup->setEnabled(false);
	ui_.pb_accept->setEnabled(false);
	ui_.pb_reject->setEnabled(false);

	connect(ui_.pb_hangup,SIGNAL(clicked()),SLOT(terminate_call()));
	connect(ui_.pb_accept,SIGNAL(clicked()),SLOT(accept_call()));
	connect(ui_.pb_reject,SIGNAL(clicked()),SLOT(reject_call()));
	
}
Пример #2
0
void VoiceCallDlg::finalize()
{
	// Close connection
	if (status_ == Incoming) {
		reject_call();
	}
	else if (status_ == InProgress || status_ == Calling || status_ == Accepting || status_ == Accepted) {
		terminate_call();
	}

	// Disconnect signals
	disconnect(voiceCaller_,SIGNAL(accepted(const Jid&)),this,SLOT(accepted(const Jid&)));
	disconnect(voiceCaller_,SIGNAL(rejected(const Jid&)),this,SLOT(rejected(const Jid&)));
	disconnect(voiceCaller_,SIGNAL(in_progress(const Jid&)),this,SLOT(in_progress(const Jid&)));
	disconnect(voiceCaller_,SIGNAL(terminated(const Jid&)),this,SLOT(terminated(const Jid&)));
}
Пример #3
0
int b2bl_callback_customer(b2bl_cb_params_t *params, unsigned int event)
{
	struct cc_call *call = (struct cc_call*)params->param;
	str leg = {NULL,0};
	call_state cs;
	int cnt;
	b2bl_dlg_stat_t* stat = params->stat;

	LM_DBG(" call (%p) has BYE for %d, \n", call, event);

	lock_get( call->lock );
	cs = call->state;

	if (event==B2B_DESTROY_CB) {
		LM_DBG("A delete in b2blogic, call->state=%d, %p\n", call->state, call);
		call->state = CC_CALL_ENDED;
		lock_release( call->lock );
		if( cs != CC_CALL_ENDED) {
			/* call terminated due to some error -> cleanup here */
			terminate_call( call, NULL, cs);
			if (cs < CC_CALL_TOAGENT) {
				LM_DBG("** onhold-- Destroy [%p]\n", call);
				update_stat( stg_onhold_calls, -1);
				update_stat( call->flow->st_onhold_calls, -1);
			}
			if (cs == CC_CALL_TOAGENT) {
				/* call no longer on wait */
				//update_stat( stg_aban_incalls, 1); /*abandon from agent */
				//update_stat( call->agent->st_aban_incalls, 1);
			}
		}
		lock_get( call->lock );
		cnt = --call->ref_cnt;
		lock_release( call->lock );
		if (cnt==0)
			free_cc_call( data, call);
		else
			LM_DBG("!!! Call ref not 0 - do not delete %p\n", call);
		return 0;
	}

	if(call->ign_cback) {
		lock_release( call->lock );
		return 2;
	}

	if ( event==B2B_BYE_CB ) {
		if (cs==CC_CALL_TOAGENT && stat->call_time) {
			/* an established call was terminated */
			update_stat( stg_answ_incalls, 1);
			update_stat( call->flow->st_answ_incalls, 1);
			call->fst_flags |= FSTAT_ANSW;
			update_stat( call->agent->st_answ_incalls, 1);
		}
	}
	
	if (event==B2B_BYE_CB && params->entity==1) {
		LM_DBG("BYE from the customer\n");
		/* external caller terminated the call */
		call->state = CC_CALL_ENDED;
		lock_release( call->lock );
		if (cs<CC_CALL_TOAGENT) {
			/* call terminated while onwait */
			LM_DBG("** onhold-- BYE from customer [%p]\n", call);
			update_stat( stg_onhold_calls, -1);
			update_stat( call->flow->st_onhold_calls, -1);
		}
		/* Abandon: client was not sent to agent yet, or call still ringing
		 * on agent side
		 */
		if (cs<CC_CALL_TOAGENT || stat->call_time==0) {
 			/*abandon from customer */
			update_stat( stg_aban_incalls, 1);
			update_stat( call->flow->st_aban_incalls, 1);
			call->fst_flags |= FSTAT_ABAN;
		}
		terminate_call(call, stat, cs);

		/* route the BYE according to scenario */
		return 2;
	}
	/* if reInvite to the customer failed - end the call */
	if(event == B2B_REJECT_CB && params->entity==1) {
		lock_release( call->lock );
		return 1;
	}

	if(event == B2B_REJECT_CB && params->entity>1) {
		if(call->state == CC_CALL_TOAGENT) {
			handle_agent_reject(call, 1, stat->setup_time);
			lock_release( call->lock );
			return 0;
		}
		lock_release( call->lock );
		return 1;
	}

	if (stat->call_time==0 && call->state == CC_CALL_TOAGENT) {
		LM_INFO("*** AGENT answered and closed immediately %.*s\n",
			call->agent->location.len, call->agent->location.s);
		handle_agent_reject(call, 1, stat->setup_time);
		lock_release( call->lock );
		return 0;
	}
	
	/* right-side leg of call sent BYE -> get next state */
	lock_get( data->lock );

	if (cc_call_state_machine( data, call, &leg )!=0) {
		LM_ERR("failed to get next call destination \n");
		lock_release( data->lock );
		lock_release( call->lock );
		/* force BYE to be sent in both parts */
		return -1;
	}

	lock_release( data->lock );

	LM_DBG("new destination for call(%p) is %.*s (state=%d)\n",
		call, leg.len, leg.s, call->state);

	if (call->state == CC_CALL_ENDED) {
		lock_release( call->lock );
		terminate_call( call, stat, cs);
		return 2;
	} else if (call->state == CC_CALL_TOAGENT) {
		/* call no longer on wait */
		LM_DBG("** onhold-- Direct to agent [%p]\n", call);
		update_stat( stg_onhold_calls, -1);
		update_stat( call->flow->st_onhold_calls, -1);
	}

	/* send call to selected destination */
	if (set_call_leg( NULL, call, &leg)< 0) {
		LM_ERR("failed to set new destination for call\n");
		lock_release( call->lock );
		pkg_free(leg.s);
		return -1;
	}
	lock_release( call->lock );

	if(cc_db_update_call(call) < 0)
	{
		LM_ERR("Failed to update call in database\n");
	}

	pkg_free(leg.s);
	return 0;
}