void voice_card_control::cti_callout(boost::shared_ptr<cti_call_out_param> cti_call_out_param_)
{
	std::size_t chID;
	try
	{
		chID = m_channel_queue.take();
	}
	catch (std::out_of_range)
	{
		BOOST_LOG_SEV(cia_g_logger, RuntimeInfo) << "业务流水:" << cti_call_out_param_->m_transId << " 获取通道失败, 通道全部繁忙";
		//继续下一次呼叫
		cti_callout_again(cti_call_out_param_);
		return;
	}
	BOOST_LOG_SEV(cia_g_logger, RuntimeInfo) << "业务流水:" << cti_call_out_param_->m_transId << " 获取到得通道状态为:" << SsmChkAutoDial(chID) << ", 通道号码:" << chID;
	SsmSetTxCallerId(chID, cti_call_out_param_->m_authCode.c_str());
	if (SsmAutoDial(chID, cti_call_out_param_->m_pn.c_str()) == 0){
		BOOST_LOG_SEV(cia_g_logger, RuntimeInfo) << "业务流水:" << cti_call_out_param_->m_transId << " 已发送请求, 已将此通道对应状态清空, 通道号码:" << chID;
		boost::shared_ptr<trunk> t = m_trunk_vector.at(chID);
		boost::unique_lock<boost::mutex> unique_lock_(t->m_trunk_mutex, boost::defer_lock);
		if (unique_lock_.try_lock())
		{
			t->m_client_socket = cti_call_out_param_->m_base_client;
			t->m_transId = cti_call_out_param_->m_transId;
			t->m_caller_id = cti_call_out_param_->m_authCode;
			t->m_called_id = cti_call_out_param_->m_pn;
			t->m_hungup_by_echo_tone = cti_call_out_param_->m_hungup_by_echo_tone;
			t->m_step = TRK_CALLOUT_DAIL;
			t->m_callTime.restart();
		}
		else
		{
			BOOST_LOG_SEV(cia_g_logger, Critical) << "业务流水:" << cti_call_out_param_->m_transId << ", 严重异常, 被分配的语音通道处于占用状态, 请程序猿通宵解决问题";
		}
	}
	else {
		m_channel_queue.put(chID);
		//上一次呼叫失败,继续呼叫
		if (cti_call_out_param_->m_repeat_call_out)
		{
			cti_call_out_param_->m_repeat_call_out = false;
			BOOST_LOG_SEV(cia_g_logger, RuntimeInfo) << "业务流水:" << cti_call_out_param_->m_transId << "上一次呼叫失败,继续呼叫";
			cti_callout_again(cti_call_out_param_);
		}
		//已经连续两次呼叫失败, 直接返回失败
		else
		{
			BOOST_LOG_SEV(cia_g_logger, RuntimeInfo) << "业务流水:" << cti_call_out_param_->m_transId << "已经连续两次呼叫失败, 直接返回失败";
			ciaMessage msg;
			msg.set_type(CIA_CALL_RESPONSE);
			msg.set_transid(cti_call_out_param_->m_transId);
			msg.set_status(CIA_CALL_FAIL);
			cti_call_out_param_->m_base_client->do_write(chat_message(msg));
			return;
		}
	}
}
void voice_card_control::cti_callout(boost::shared_ptr<cti_call_out_param> cti_call_out_param_)
{
	std::size_t chID;
	ciaMessage& msg_ = cti_call_out_param_->m_ch_msg->m_procbuffer_msg;
	try
	{
		chID = m_channel_queue.take();
	}
	catch (std::out_of_range)
	{
		//BOOST_LOG_SEV(cia_g_logger, RuntimeInfo) << "业务流水:" << msg_.transid() << " 获取通道失败, 通道全部繁忙";
		//继续下一次呼叫
		cti_callout_again(cti_call_out_param_);
		return;
	}
	int ch_state = SsmGetChState(chID);
	if (ch_state != 0 && ch_state != 123) //空闲或本地闭塞
	{
		BOOST_LOG_SEV(cia_g_logger, RuntimeInfo) << "业务流水:" << msg_.transid() << " , 获取到得通道状态为:" << ch_state << ", 不可用,将此通道重新放回。通道号码:" << chID;
		m_channel_queue.put(chID);
		cti_callout_again(cti_call_out_param_);
		return;
	}
	//BOOST_LOG_SEV(cia_g_logger, RuntimeInfo) << "业务流水:" << msg_.transid() << ", 获取到的通道号码:" << chID;
	SsmSetTxCallerId(chID, msg_.authcode().c_str());
	boost::shared_ptr<trunk> t = m_trunk_vector.at(chID);
	boost::unique_lock<boost::mutex> unique_lock_(t->m_trunk_mutex);
	if (SsmAutoDial(chID, msg_.pn().c_str()) == 0){
		BOOST_LOG_SEV(cia_g_logger, RuntimeInfo) << "业务流水:" << msg_.transid() << " 已发送请求, 已将此通道对应状态清空, 通道号码:" << chID;				
		t->reset_trunk(cti_call_out_param_);
	}
	else {
		show_error();
		unique_lock_.unlock();
		m_channel_queue.put(chID);
		//上一次呼叫失败,继续呼叫
		if (cti_call_out_param_->m_repeat_call_out)
		{
			cti_call_out_param_->m_repeat_call_out = false;
			BOOST_LOG_SEV(cia_g_logger, RuntimeInfo) << "业务流水:" << msg_.transid() << "上一次呼叫失败,继续呼叫, 失败原因向上查询SsmGetLastErrMsg";
			cti_callout_again(cti_call_out_param_);
		}
		//已经连续两次呼叫失败, 直接返回失败
		else
		{
			BOOST_LOG_SEV(cia_g_logger, RuntimeInfo) << "业务流水:" << msg_.transid() << "已经连续两次呼叫失败, 直接返回失败, 失败原因向上查询SsmGetLastErrMsg";
			std::string transid_ = msg_.transid();
			msg_.Clear();
			msg_.set_type(CIA_CALL_RESPONSE);
			msg_.set_transid(transid_);
			msg_.set_status(CIA_CALL_FAIL);
			cti_call_out_param_->m_base_client->do_write(cti_call_out_param_->m_ch_msg);
			return;
		}
	}
}