⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 d300.cpp

📁 170话费查询系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#include "stdafx.h"  //这个头文件一定要加,不然编译通不过
#include <time.h>

#include "mybase.h"
#include "myvc.h"
#include "d300.h"

//状态机表
MachineState    MST[]={
/*		线程			状态			事件		下一线程		下一状态	超时*/
{1,		_main,		waiting_call,	call_coming,	_main,			read_ani,	-1},	
{2,		_main,		read_ani,		ani_recieve,	_main,			verify_ani,	-1},
{3,		_main,		verify_ani,		ani_valid,		_main,			wel_play,	-1},
{4,		_main,		verify_ani,		ani_invalid,	_timeout,		tm_anirefuse,-1},
{5,		_main,		wel_play,		play_over,	_main,			vm_1_play,	-1},

{6,		_main,		vm_1_play,		cmd0_switch,	_singleinput,	sgipt_start,10000},
{7,		_main,		main_sleep,		cmd0_hf,		_main,			hf_play,	-1},
{8,		_main,		main_sleep,		cmd0_xd,		_main,			xd_play,	-1},
{9,		_main,		main_sleep,		cmd0_qf,		_main,			qry_hint,	-1},
{10,	_main,		main_sleep,		cmd0_ad,		_main,			ad_play,	-1},

{11,	_main,		hf_play,		cmd1_switch,	_singleinput,	sgipt_start,10000},
{12,	_main,		main_sleep,		cmd1_qry_djdy,	_main,			qry_hint,	-1},
{13,	_main,		main_sleep,		cmd1_qry_tshou,	_main,			qry_hint,	-1},
{14,	_main,		xd_play,		cmd2_switch,	_singleinput,	sgipt_start,10000},
{15,	_main,		main_sleep,		cmd2_qry_ctxd,	_main,			qry_hint,	-1},
{16,	_main,		main_sleep,		cmd2_qry_bdwxd,	_main,			qry_hint,	-1},
{17,	_main,		main_sleep,		cmd2_qry_168xd,	_main,			qry_hint,	-1},

{19,	_main,		ad_play,		play_over,		_main,		ad_asknext	,-1},
{19,	_main,		ad_asknext,		cmd3_switch,	_singleinput,	sgipt_start,	10000},


{20,	_main,		qry_hint,		month_switch,	_monthinput,	mth_start,-1},
{21,	_main,		main_sleep,		month_get,		_main,			qry_data,	-1},
{22,	_main,		qry_data,		qry_ok,			_main,			play_result,-1},
{23,	_main,		qry_data,		qry_timeout,	_timeout,		tm_start,	-1},
{24,	_main,		play_result,	play_switch,	_multiplay,		mply_start,	-1},

{25,	_singleinput,	sgipt_idle,		sgipt_start,	_singleinput,	sgipt_waitkey,	-1},
{26,	_singleinput,	sgipt_waitkey,	sgipt_keypress,	_singleinput,	sgipt_verify,	10000},
{26,	_singleinput,	sgipt_waitkey,	sgipt_timeout,	_timeout,		tm_start,	-1},
{27,	_singleinput,	sgipt_verify,	sgipt_keyerr,	_singleinput,	sgipt_playerr,	-1},
{28,	_singleinput,	sgipt_playerr,	sgipt_errover,	_nodefine,		_nodefine,	-1},
{29,	_singleinput,	sgipt_verify,	sgipt_alwayserr,_timeout,		tm_start,	-1},

{30,	_monthinput,	mth_idle,		mth_start,		_monthinput,	mth_playmonth,	-1},
{31,	_monthinput,	mth_playmonth,	mth_numget,		_monthinput,	mth_check,	-1},
{32,	_monthinput,	mth_playmonth,	mth_monthover,	_monthinput,	mth_wait,	-1},
{33,	_monthinput,	mth_wait,		mth_timeout,	_timeout,		tm_start,	-1},
{33,	_monthinput,	mth_wait,		mth_numget,		_monthinput,	mth_check,	-1},
{34,	_monthinput,	mth_check,		mth_numerr,		_monthinput,	mth_playerr,	-1},
{35,	_monthinput,	mth_check,		mth_nodata,		_monthinput,	mth_playnodata,	-1},
{36,	_monthinput,	mth_check,		mth_alwayserr,	_timeout,		tm_start,	-1},
{37,	_monthinput,	mth_check,		mth_valid,		_main,			tm_start,	-1},
{37,	_monthinput,	mth_playerr,	play_over,	_monthinput,		mth_start,	-1},
{37,	_monthinput,	mth_playnodata,	play_over,	_monthinput,		mth_start,	-1},

{38,	_multiplay,		mply_idle,		mply_start,		_multiplay,		mply_chkdata,	-1},
{39,	_multiplay,		mply_chkdata,	mply_nodata,	_multiplay,		mply_playnodata,	-1},
{39,	_multiplay,		mply_chkdata,	mply_chkok,		_multiplay,		mply_playing,	-1},
{39,	_multiplay,		mply_playnodata,	play_over,		_multiplay,		mply_asknext,	-1},
{39,	_multiplay,		mply_playing,	play_over,		_multiplay,		mply_chknext,	-1},
{39,	_multiplay,		mply_chknext,	mply_nextok,	_multiplay,		mply_playing,	-1},
{39,	_multiplay,		mply_chknext,	mply_nextnull,	_multiplay,		mply_asknext,	-1},
{40,	_multiplay,		mply_asknext,	cmd4_switch,	_singleinput,	sgipt_start,	10000},
{41,	_multiplay,		mply_sleep,		cmd4_replay,	_multiplay,		voc_reset,	-1},
{42,	_multiplay,		voc_reset,		voc_resetok,	_multiplay,		mply_chkdata,	-1},

{43,	_timeout,	tm_idle,		tm_start,		_timeout,	tm_check,		-1},
{44,	_timeout,	tm_systmout,	tm_check,		_timeout,	play_systmout,	-1},
{45,	_timeout,	tm_usertmout,	tm_check,		_timeout,	play_usertmout,	-1},
{46,	_timeout,	tm_alwayserr,	tm_check,			_timeout,	play_usertmout,	-1},
{47,	_timeout,	tm_userhangup,	tm_check,			_timeout,	tm_voc_hangup,	-1},
{48,	_timeout,	tm_anirefuse,	tm_check,			_timeout,	tm_voc_hangup,	-1},
{49,	_timeout,	play_systmout,	play_sysover,	_timeout,	play_bye,		-1},
{50,	_timeout,	play_usertmout,	play_userover,	_timeout,	play_bye,		-1},
{51,	_timeout,	play_bye,		play_byeover,	_timeout,	tm_voc_hangup,	-1},
{52,	_timeout,	tm_voc_hangup,	tm_restart,		_main,		month_get,		-1},
{_nodefine,	_nodefine,	_nodefine,	_nodefine,		_nodefine,		_nodefine,		-1},
};

//语音卡名
char *voxchannels[] = {
   "dxxxB1C1" , "dxxxB1C2" , "dxxxB1C3" , "dxxxB1C4",
   "dxxxB2C1" , "dxxxB2C2" , "dxxxB2C3" , "dxxxB2C4",
   "dxxxB3C1" , "dxxxB3C2" , "dxxxB3C3" , "dxxxB3C4",
   "dxxxB4C1" , "dxxxB4C2" , "dxxxB4C3" , "dxxxB4C4",
   "dxxxB5C1" , "dxxxB5C2" , "dxxxB5C3" , "dxxxB5C4",
   "dxxxB6C1" , "dxxxB6C2" , "dxxxB6C3" , "dxxxB6C4",
   "dxxxB7C1" , "dxxxB7C2" , "dxxxB7C3" , "dxxxB7C4",
   "dxxxB8C1" , "dxxxB8C2" , 
	NULL,
};
//中继卡名
char *dtichannels[] = {
   "dtiB1T1" , "dtiB1T2" , "dtiB1T3" , "dtiB1T4",
   "dtiB1T5" , "dtiB1T6" , "dtiB1T7" , "dtiB1T8",
   "dtiB1T9" , "dtiB1T10", "dtiB1T11", "dtiB1T12",
   "dtiB1T13", "dtiB1T14", "dtiB1T15", "dtiB1T16",
   "dtiB1T17", "dtiB1T18", "dtiB1T19", "dtiB1T20",
   "dtiB1T21", "dtiB1T22", "dtiB1T23", "dtiB1T24",
   "dtiB1T25", "dtiB1T26", "dtiB1T27", "dtiB1T28",
   "dtiB1T29", "dtiB1T30", 
	NULL,
};

//线程状态表
type_SYSTHREAD		SysThread[]={
							{_dispatcher,	"事件分发线程",	true,true},
							{_main,			"主线程",	true,true},
							{_singleinput,	"读键线程",	true,true},
							{_monthinput,	"月份线程",	true,true},
							{_multiplay,	"播放线程",	true,true},
							{_timeout,		"终结线程",	true,true},
							{_timetrigger,	"计时器线程",true,true}};

//单键输入IO参数表
type_SGIPT_IO  SGIPT_io_vm1 = 
	{5,0,"", {	{'1',	_main,	cmd0_hf},			//		1  ---> 话费查询
				{'2',	_main,	cmd0_xd},			//		2  ---> 详单查询
				{'3',	_main,	cmd0_qf},			//		3  ---> 欠费查询
				{'4',	_main,	cmd0_ad},			//		4  ---> 电信业务宣传
				{'X',	_main,	vm_1_play},			//		X  ---> 错误出口
										}};

type_SGIPT_IO  SGIPT_io_hf = 
	{4,0,"", {	{'1',	_main,	cmd1_qry_djdy},		//		1 ---> 单机单月话费
				{'2',	_main,	cmd1_qry_tshou},	//		2 ---> 托收用户话费
				{'*',	_main,	vm_1_play},			//		* ---> 返回上一级菜单vm_1
				{'X',	_main,	cmd0_hf},			//		X  ---> 错误出口
										}};

type_SGIPT_IO  SGIPT_io_xd = 
	{4,0,"", {	{'1',	_main,	cmd2_qry_ctxd},		//		1 ---> 长途详单
				{'2',	_main,	cmd2_qry_bdwxd},	//		2 ---> 本地网详单
				//{'3',	_main,	cmd2_qry_168xd},	//		3 ---> 声讯详单
				{'*',	_main,	vm_1_play},			//		* ---> 返回上一级菜单vm_1
				{'X',	_main,	cmd0_xd},			//		X  ---> 错误出口
										}};
type_SGIPT_IO  SGIPT_io_adover = 
	{3,0,"", {	{'1',	_main,	cmd0_ad},			//		1 ---> 重听业务宣传
				{'*',	_main,	vm_1_play},			//		* ---> 返回上一级菜单vm_1
				{'X',	_main,	ad_asknext},		//		X ---> 错误出口
										}};
type_SGIPT_IO  SGIPT_io_mplyover = 
	{4,0,"", {	{'1',	_multiplay,		cmd4_replay},		//		1 ---> 重听结果
				{'2',	_main,			qry_hint},			//		2 ---> 重新查询
				{'*',	_main,			_nodefine},			//		* ---> 返回上一级菜单
				{'X',	_multiplay,		mply_asknext},		//		X  ---> 错误出口
				
										}};


//通道控制结构
type_CHANNEL		Channel[MAXCHAN];

//vfit
VFIT				Vfit[MaxVFIT];

//系统全局信息
type_SYSINFO		System;						
/********************************************************************/

/*************************************************************************
 *        函数 : init00(int chan)
 *		  描叙 : 初始化一个通道的全部数据结构
 *		  chan : 通道号 (1...MAXCHAN)
 *					  
 *************************************************************************/
bool init00(int chan)
{
	if (chan<1 || chan>MAXCHAN) return false;
	//通道
	Channel[chan-1].SeizedByThisApp	= ChannelSeizedByThisApp(chan, TheAppID)==1?true:false;

	Channel[chan-1].no				= chan;
	Channel[chan-1].voc				= 0;
	Channel[chan-1].dti				= 0;
	Channel[chan-1].number			= 0;
	Channel[chan-1].thread_id		= _main;
	
	strcpy(Channel[chan-1].voxname,"");
	strcpy(Channel[chan-1].dtiname,"");
	strcpy(Channel[chan-1].dnis,"");
	strcpy(Channel[chan-1].ani,"");

	Channel[chan-1].evt_handle		= 0;
	Channel[chan-1].dev_handle		= 0;
	Channel[chan-1].wait_result		= 0;

	Channel[chan-1].keybuffer[0]	= '\0';
	Channel[chan-1].keynumber		= 0;
	Channel[chan-1].lastkey			= '\0';

	//main线程
	Channel[chan-1].Main.cur_st		= waiting_call;
	strcpy(Channel[chan-1].Main.UserOp,"");
	//singleinput线程
    Channel[chan-1].SingleInput.cur_st			= sgipt_idle;
	Channel[chan-1].SingleInput.io.num			= 0;
	Channel[chan-1].SingleInput.io.errortimes	= 0;
	Channel[chan-1].SingleInput.io.buffer[0]		= '\0';
	//monthinput线程
	Channel[chan-1].MonthInput.cur_st			= mth_idle;
	Channel[chan-1].MonthInput.error_input_times = 0;
	Channel[chan-1].MonthInput.nst_valid			= _nodefine;
	Channel[chan-1].MonthInput.nth_valid			= _nodefine;
	//multiplay线程
	Channel[chan-1].MultiPlay.cur_st				= mply_idle;
	//timeout线程
	Channel[chan-1].TimeOut.cur_st				= tm_idle;
	//timetriiger线程
	Channel[chan-1].TimeTrigger.TriggerID	= chan;
	Channel[chan-1].TimeTrigger.IsCounting	= false;
	Channel[chan-1].TimeTrigger.msecond		= 0;
	Channel[chan-1].TimeTrigger.st_timeout	= _nodefine;
	Channel[chan-1].TimeTrigger.chn_timeout	= chan;

	//日志
	Channel[chan-1].ServerLog.WriteLog	= false;

	//通道总状态
	Channel[chan-1].curr_st		= waiting_call;
	

	return true;
}
/*************************************************************************
 *        函数 : init_30()
 *		  描叙 : 初始化所有通道的数据结构
 *					  
 *************************************************************************/
int init_30()
{	bool DoDebug = true;
	int		i;

	if (DoDebug) {
		SysPrintf(" ");
		SysPrintf("Open channels....");
	}

	//初始化通道结构
	for (i=1;i<=MAXCHAN;i++)
	{
		init00(i);
		if (Channel[i-1].SeizedByThisApp == true){
			ChnPrintf(i, "_USER", " ");
			ChnPrintf(i, "_STATE", "open");
			ChnPrintf(i, "_TELE", " ");
		}
	}
	


	return 0;
}

/*************************************************************************
 *        函数 : init01(int chan)
 *		  描叙 : 初始化一个通道的数据结构以及硬件状态
 *		  chan : 通道号 (1...MAXCHAN)
 *					  
 *************************************************************************/
bool init01(int chan)
{	

	if (chan<1 || chan>MAXCHAN) return false;


	//通道总状态
	Channel[chan-1].number			= 0;

	strcpy(Channel[chan-1].dnis,"");
	strcpy(Channel[chan-1].ani,"");

	Channel[chan-1].evt_handle		= 0;
	Channel[chan-1].dev_handle		= 0;
	Channel[chan-1].wait_result		= 0;

	Channel[chan-1].keybuffer[0]	= '\0';
	Channel[chan-1].keynumber		= 0;
	Channel[chan-1].lastkey			= '\0';

	Channel[chan-1].thread_id		= _main;
	Channel[chan-1].curr_st			= waiting_call;

	//main线程
	Channel[chan-1].Main.cur_st		= waiting_call;
	strcpy(Channel[chan-1].Main.UserOp,"");
	//singleinput线程
    Channel[chan-1].SingleInput.cur_st			= sgipt_idle;
	Channel[chan-1].SingleInput.io.num			= 0;
	Channel[chan-1].SingleInput.io.errortimes	= 0;
	Channel[chan-1].SingleInput.io.buffer[0]		= '\0';
	//monthinput线程
	Channel[chan-1].MonthInput.cur_st			= mth_idle;
	Channel[chan-1].MonthInput.error_input_times = 0;
	Channel[chan-1].MonthInput.nst_valid			= _nodefine;
	Channel[chan-1].MonthInput.nth_valid			= _nodefine;
	//multiplay线程
	Channel[chan-1].MultiPlay.cur_st				= mply_idle;
	//timeout线程
	Channel[chan-1].TimeOut.cur_st				= tm_idle;
	//timetriiger线程
	Channel[chan-1].TimeTrigger.TriggerID	= chan;
	Channel[chan-1].TimeTrigger.IsCounting	= false;
	Channel[chan-1].TimeTrigger.msecond		= 0;
	Channel[chan-1].TimeTrigger.st_timeout	= _nodefine;
	Channel[chan-1].TimeTrigger.chn_timeout	= chan;
	//日志
	Channel[chan-1].ServerLog.WriteLog		= false;
	
	dt_settssigsim(Channel[chan-1].dti,DTB_AON|DTB_BOFF|DTB_CON|DTB_DON);

	return true;
}

/*************************************************************************
 *        函数 : init_voice()
 *		  描叙 : 打开语音卡
 *					  
 *        参数 : 无
 *		  说明 : 根据semaphore的配置,打开查询程序的全部端口
 *        返回 : 打开并占用的端口数量,<=0 表示打开失败.
 *************************************************************************/
int init_voice(void)
{
	bool DoDebug = false;
	char cn[10];
	int mode;
	int i, count;

	if (DoDebug) {
		SysPrintf("启动语音卡....");
	}

	//初始化全局信息表
	strcpy(cn, (const char *)ReadGCA("ChannelNumber"));
	System.ChannelNumber = atoi(cn);
	if (DoDebug) {
		SysPrintf("通道总数=%d", System.ChannelNumber);
	}
    	
	// 设置语音卡为轮询问模式
	mode = SR_POLLMODE;
	if (sr_setparm(SRL_DEVICE,SR_MODEID,&mode )==-1) {    
		WinPrintf("sr_setparm(): error\n");
		exit(0);
	}

	count = 0;
	//打开所有端口
	for (i=0; i <MAXCHAN; i++) {
        //判断端口是否由本程序来占用
		if (! ChannelSeizedByThisApp(i+1, TheAppID))  continue;
		
		strcpy(Channel[i].voxname,voxchannels[i]);		
		if ((Channel[i].voc = dx_open(Channel[i].voxname, 0)) == -1) {
			WinPrintf("%s: Error opening this channel\n",Channel[i].voxname);
			exit(1);
		}
		//打开中继卡端口
		strcpy(Channel[i].dtiname,dtichannels[i]);
		if ((Channel[i].dti = dt_open(Channel[i].dtiname, 0)) == -1) {
			WinPrintf("%s: Error opening this channel\n",Channel[i].dtiname);
			exit(1);
		}
	
		//连接语音卡和中继卡两种设备。这里涉及到 SCBus,SCBus是Dialogic公司的一种硬件
		//技术,用于连接不同的DEVICE. D300/SC-E1卡其实就是用SCBus连接一个30路语音卡
		//和一个30口中继卡为一体的产品。
		// nr_nr_scunroute()函数的作用在于断开 dit 和 voice之间的连接。
		if(nr_scunroute(Channel[i].dti,SC_DTI,Channel[i].voc,SC_VOX,SC_FULLDUP)==-1){
			WinPrintf("%s <=== UnRoute Failed ===> %s\n",Channel[i].voxname,Channel[i].dtiname);
			exit(1);
		}
		
		//重建 dti 和voice之间的全双工连接。
		if(nr_scroute(Channel[i].dti,SC_DTI,Channel[i].voc,SC_VOX,SC_FULLDUP)==-1){
			WinPrintf("%s <=== Route Failed ===> %s\n",Channel[i].voxname,Channel[i].dtiname);
			exit(1);
		}

		//语音卡要监听来自交换机的前向信号( R2MF, forward signal),必须调用 r2_createfsig
		//建立一个模板(template),指定监听哪些signal, dx_deltons()则是清除这个template.
		if(dx_deltones(Channel[i].voc)==-1){
			WinPrintf("%s: dx_deltones()\n",Channel[i].voxname);
			exit(1);
		}
	
		//重建template,指定端口监听所有的(forward signal)
		if(r2_creatfsig(Channel[i].voc,R2_ALLFSIG)==-1){
			WinPrintf("%s: r2_creatfsig()\n",Channel[i].voxname);
			exit(1);
		}
	
		//数字设备上有一个传输信号字节Bitmask,用于表示事件,其bitmask有如下
		/* DTB_AON - "A" signaling bit on 
		   DTB_AOFF - "A" signaling bit off 
		   DTB_BON - "B" signaling bit on 
		   DTB_BOFF - "B" signaling bit off 
		   DTB_CON - "C" signaling bit on (E-1 only) 
		   DTB_COFF - "C" signaling bit off (E-1 only) 
		   DTB_DON - "D" signaling bit on (E-1 only) 
		   DTB_DOFF - "D" signaling bit off (E-1 only) */		   
		if(dt_settssigsim(Channel[i].dti,DTB_AON|DTB_BOFF|DTB_CON|DTB_DON)==-1){
			WinPrintf("dt_settssig() in dt_onhook(1)\n");
			exit(1);
		}
		
			
		//chan_init(i);
		strcpy(Channel[i].dnis,"");
		strcpy(Channel[i].ani,"");
		Channel[i].number=0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -