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

📄 d300.cpp

📁 170话费查询系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 * voc_index: 语音索引文件名
 * fandle	: 用于保存语音文件句柄的指针
 * offset	: 用于保存语音文件位置的指针
 * length	: 用于保存语音文件长度的指针
 ***************************************************************************/
int get_voc_descr(char * voc_index, int * fhandle, int * offset, int *length)
{
	int		count = 1;
	char	s_indexname1[40], s_indexname2[40], s_fhandle[10], s_offset[10], s_length[10];
	

	strcpy(s_indexname1, voc_index);
	upstring(s_indexname1,s_indexname1);

	while (count <= System.VocNumber)
	{
		//itoa(count,scount,10);
		//strcpy(s_indexname2,(const char *) ReadVFIT(scount, "indexname"));
		strcpy(s_indexname2, Vfit[count-1].indexname);
		upstring(s_indexname2, s_indexname2);
		
		if (strcmp(s_indexname1, s_indexname2)==0) { // voc found!
			strcpy(s_fhandle,Vfit[count-1].filehandle);			
			strcpy(s_offset,Vfit[count-1].io_offset);
			strcpy(s_length,Vfit[count-1].io_length);

			(*fhandle) = atoi(s_fhandle);
			(*offset) = atoi(s_offset);
			(*length) = atoi(s_length);
			return 1;
		}
		count ++;
	}

	return -1;
}


/***************************************************************************
 * 函数:   int play_voc(int cn, char * voc_index)
 * 
 * Des : 在通道cn上播放语音 voc_index
 * cn	: 通道号
 * voc  : 语音索引名

 ***************************************************************************/
int play_voc(int cn, char * voc_index, bool key_break)
{
   int fhandle, io_offset, io_length;
   DV_TPT play_tpt;

   // Set to terminate play on 1 digit
   if (key_break == true)
   {
	play_tpt.tp_type	= IO_EOT; 
	play_tpt.tp_termno	= DX_MAXDTMF; 
	play_tpt.tp_length	= 1; 
	play_tpt.tp_flags	= TF_MAXDTMF; 
   }

 	if (get_voc_descr(voc_index, &fhandle, &io_offset, &io_length)==-1) {
		SysPrintf("没有找到语音(%s)的数据",voc_index);
		return -1;
	}

	//数据传输表
	Channel[cn-1].iott.io_type= IO_DEV | IO_EOT;
	Channel[cn-1].iott.io_bufp=0;
	Channel[cn-1].iott.io_offset= io_offset;
	Channel[cn-1].iott.io_length= io_length;
	Channel[cn-1].iott.io_fhandle= fhandle;
	
	
	//传输参数表
    Channel[cn-1].xpb.wFileFormat = FILE_FORMAT_VOX;
	Channel[cn-1].xpb.wDataFormat = DATA_FORMAT_DIALOGIC_ADPCM;
	Channel[cn-1].xpb.nSamplesPerSec = DRT_8KHZ;
	Channel[cn-1].xpb.wBitsPerSample = 4;

	dx_clrdigbuf(Channel[cn-1].voc);

	//播放
	if (dx_playiottdata(Channel[cn-1].voc,&Channel[cn-1].iott,&play_tpt,&(Channel[cn-1].xpb),EV_ASYNC)==-1 ){
		SysPrintf("%s: %s in dx_playiottdata()\n",Channel[cn-1].voxname,ATDV_ERRMSGP(Channel[cn-1].voc));
		return -1;
    }	

	ChnPrintf(cn,"_STATE", "Playing \'%s\'...",voc_index);

	return 1;

}

/*************************************************************************
*   FUNC:	time_trigger_func(LPVOID pParam) 
*   
*	说明:	计时器线程,以秒计
*	
*   
************************************************************************/
UINT time_trigger_func(LPVOID pParam) 
{
   int cn;

   SysPrintf("Time Trigger 启动.");

   System.SysThreadNumber ++;

   while (SysThread[_timetrigger].keep_running) 
   {

		for (cn = 1; cn<MAXCHAN; cn++)
		{
			Sleep(0); //相当于 yield()
			if (Channel[cn-1].TimeTrigger.IsCounting == true) //处于计时状态
			{
				if (Channel[cn-1].TimeTrigger.msecond > 0) {
					Channel[cn-1].TimeTrigger.msecond--;
				}
				else
				{   //时间到
					Channel[cn-1].TimeTrigger.msecond = 0;
					Channel[cn-1].TimeTrigger.IsCounting = false;
					SysPrintf("(%d)Time Trigger 触发超时事件 !",cn);
				    put_event_to_board(cn,Channel[cn-1].TimeTrigger.event);
				}
			}
		}
	Sleep(1000);  //停顿1秒
   }

	SysPrintf("Time Trigger     退出!");

	--System.SysThreadNumber;
	if (System.SysThreadNumber == 0) {
		System.AllThreadClosed.SetEvent();
	}
   return 1; 
   
}  //end of time_trigger_func()

/*************************************************************************
*   FUNC:	start_time_trigger() 
*   
*	说明:	启动计时器线程
*	
*   
************************************************************************/
void start_time_trigger()
{
	SysThread[_timetrigger].pThread = ::AfxBeginThread(time_trigger_func, NULL);
	return;
}
/*************************************************************************
*   函数:	stop_timing(int cn)
*   
*	功能:	终止通道的超时计算
*	参数:  cn		: 通道号
*   
************************************************************************/
int		stop_timing(int cn)
{
		Channel[cn-1].TimeTrigger.event			= _nodefine;
		Channel[cn-1].TimeTrigger.msecond 		= 0;
		Channel[cn-1].TimeTrigger.IsCounting 	= false;
		return 0;
}

/*************************************************************************
*   函数:	start_timing(int cn, int  second, STATE evt_put)
*   
*	功能:	启动通道的超时计算
*	参数:  cn		: 通道号
*			second	: 时限(以秒为单位)
*			evt_put : 超时后通道上写的事件
*   
************************************************************************/
int		start_timing(int cn, int  second, STATE evt_put)
{
		Channel[cn-1].TimeTrigger.event			= evt_put;
		Channel[cn-1].TimeTrigger.msecond 		= second;
		Channel[cn-1].TimeTrigger.IsCounting 	= true;

		return 0;
}


/*************************************************************************
*   函数: int set_singleinput_io(int cn, type_SGIPT_IO * io_param) 
*   
*	功能:  设置 singleinput thread 的切换参数表
*	参数:
*		cn			: 通道号
*		io_param	: 切换参数表
*   
************************************************************************/
int set_singleinput_io(int cn, type_SGIPT_IO * io_param)
{
	int i = 0;
	
	// 设置IO参数表
	Channel[cn-1].SingleInput.cur_st = sgipt_idle;

	Channel[cn-1].SingleInput.io.num		=	io_param->num;
	//Channel[cn-1].SingleInput.io.errortimes	=	io_param->errortimes;
	strcpy(Channel[cn-1].SingleInput.io.buffer,io_param->buffer);
	// 复制"值--向"表
	while (i < io_param->num)
	{
		Channel[cn-1].SingleInput.io.keytable[i].key			= io_param->keytable[i].key;
		Channel[cn-1].SingleInput.io.keytable[i].goto_thread	= io_param->keytable[i].goto_thread;
		Channel[cn-1].SingleInput.io.keytable[i].goto_state		= io_param->keytable[i].goto_state;
		i++;
	}

	return 1;
}


/*************************************************************************
*   函数: int  adjust_singleinput_io(int cn)
*   
*	功能:  修正 singleinput thread 的切换参数表
*	参数:
*		cn			: 通道号
*		
*   
************************************************************************/
int  adjust_singleinput_io(int cn)
{
	static int	i = 2;  //返回上一级菜单查询
	char	Cur_UserOp[40];
	
	strcpy(Cur_UserOp,Channel[cn-1].Main.UserOp);
	//欠费查询
	if (strcmp(Cur_UserOp,Query_QF)==0) {				
		Channel[cn-1].SingleInput.io.keytable[i].goto_state		= vm_1_play;
		return 0;
	}
	//单机单月
	if (strcmp(Cur_UserOp,Query_DJDY)==0) {				
		Channel[cn-1].SingleInput.io.keytable[i].goto_state		= cmd0_hf;
		return 0;
	}
	//托收查询
	if (strcmp(Cur_UserOp,Query_TSHOU)==0) {				
		Channel[cn-1].SingleInput.io.keytable[i].goto_state		= cmd0_hf;
		return 0;
	}
	//168详单
	if (strcmp(Cur_UserOp,Query_168XD)==0) {
		Channel[cn-1].SingleInput.io.keytable[i].goto_state		= cmd0_xd;
		return 0;
	}
	//本地网详单
	if (strcmp(Cur_UserOp,Query_BDWXD)==0) {
		Channel[cn-1].SingleInput.io.keytable[i].goto_state		= cmd0_xd;
		return 0;
	}
	//长途详单
	if (strcmp(Cur_UserOp,Query_CTXD)==0) {				
		Channel[cn-1].SingleInput.io.keytable[i].goto_state		= cmd0_xd;
		return 0;
	}

	return 0;
}

/*************************************************************************
*   函数: int switch_thread(int cn, TRHEAD next_thread, STATE next_state)
*   
*	功能:  切换线程
*	参数:
*		cn		: 通道号
*		next_thread	: 下一线程
*		next_state	: 下一状态
*   
************************************************************************/
int switch_thread(int cn, THREAD next_thread, STATE next_state)
{
	int i = 0;
	
	// 设置当前线程状态
	switch (Channel[cn-1].thread_id){	
			case	_main:
					Channel[cn-1].Main.cur_st			= main_sleep;			
					break;			
			case	_singleinput:
					Channel[cn-1].SingleInput.cur_st	= sgipt_idle;
					break;			
			case	_monthinput:
					Channel[cn-1].MonthInput.cur_st	= mth_idle;
					break;					
			case	_multiplay:
					Channel[cn-1].MultiPlay.cur_st	= mply_idle;
					break;					
			case	_timeout:
					Channel[cn-1].TimeOut.cur_st	= tm_idle;
					break;			
			default:
					WinPrintf("switch_thread():error thread_id = %d",Channel[cn-1].thread_id);
	}
	

	// 设置下一当前线程
	Channel[cn-1].thread_id = next_thread;
	// 设置下一状态
	put_event_to_board(cn,next_state);	
	//ChnPrintf(cn,"_STATE", "已切换至线程%d",next_thread);
	
	return 1;
}


/*************************************************************************
*   FUNC:	int  post_read_command_to_board(int cn, int number=1)
*   
*	说明:	启动读键命令
*	参数:	cn = 通道号,number = 读键个数(默认参数,不指定则
*		等于1。
*   
************************************************************************/
int  post_read_command_to_board(int cn, int number)
{	
	int mode = EV_ASYNC; //异步读

	if (number < 1)	return 0;
	//设置终止参数表 dig_tpt
		
	// 1.读键个数 = number
	Channel[cn-1].dig_tpt[0].tp_type 	= IO_CONT;
	Channel[cn-1].dig_tpt[0].tp_termno 	= DX_MAXDTMF;
	Channel[cn-1].dig_tpt[0].tp_length 	= number;
	Channel[cn-1].dig_tpt[0].tp_flags 	= TF_MAXDTMF;	// define in ATDX_TERMMSK()

	if ( number > 1){
		// 2.总持续时间 = number * MaxWaitKeyTime
		Channel[cn-1].dig_tpt[1].tp_type 	= IO_CONT;
		Channel[cn-1].dig_tpt[1].tp_termno 	= DX_MAXTIME;
		Channel[cn-1].dig_tpt[1].tp_length 	= number * MaxWaitKeyTime *100; //(0.1 秒为单位)
		Channel[cn-1].dig_tpt[1].tp_flags 	= TM_MAXTIME;		
		// 3.键与键之间的延续时间 = MaxWaitKeyTime
		Channel[cn-1].dig_tpt[2].tp_type 	= IO_EOT;
		Channel[cn-1].dig_tpt[2].tp_termno 	= DX_IDDTIME;
		Channel[cn-1].dig_tpt[2].tp_length 	= number * MaxWaitKeyTime * 100;
		Channel[cn-1].dig_tpt[2].tp_flags 	= TM_IDDTIME;
	}
	else{
		// 2.总持续时间 = number * MaxWaitKeyTime
		Channel[cn-1].dig_tpt[1].tp_type 	= IO_EOT;
		Channel[cn-1].dig_tpt[1].tp_termno 	= DX_MAXTIME;
		Channel[cn-1].dig_tpt[1].tp_length 	= number * MaxWaitKeyTime * 100;
		Channel[cn-1].dig_tpt[1].tp_flags 	= TM_MAXTIME;
		
	}
	//if (dx_clrdigbuf(Channel[cn-1].voc) == -1) {
	//	WinPrintf("post_read_command_to_board():错误:%s!", ATDV_ERRMSGP(Channel[cn-1].voc));
	//	return -1;		
	//}

    if(dx_getdig(Channel[cn-1].voc, Channel[cn-1].dig_tpt, &(Channel[cn-1].digp),mode) == -1) 
	{
		WinPrintf("post_read_command_to_board():错误:%s!", ATDV_ERRMSGP(Channel[cn-1].voc));
		return -1;
	}
	return 1;
}


/*************************************************************************
*   FUNC:	int  read_the_key(int cn)
*   
*	说明:	读接收到的键
*	参数:	cn = 通道号,
*   
************************************************************************/
int	read_the_key(int cn)
{
	int i= 0;


	while (Channel[cn-1].digp.dg_value[i]!='\0')         //读到
	{			 
		Channel[cn-1].lastkey = Channel[cn-1].digp.dg_value[i]; 
		Channel[cn-1].keybuffer[Channel[cn-1].keynumber++] = Channel[cn-1].digp.dg_value[i]; 
       	Channel[cn-1].keybuffer[Channel[cn-1].keynumber]   = '\0';	    	    	
		i++;
		ChnPrintf(cn,"_USER","用户按键={%s}",Channel[cn-1].keybuffer);
	}
	 //读完后清空数字缓冲区		
	 Channel[cn-1].digp.dg_value[0]='\0';  //人工清除
	 return i;
}

/*************************************************************************
*   FUNC:	int  end_this_read(int cn)
*   
*	说明:	结束读键命令,清空读键缓冲区
*	参数:	cn = 通道号
*   
************************************************************************/
void          end_this_read(int cn)
{  
	dx_stopch(Channel[cn-1].voc, EV_ASYNC);
	dx_clrdigbuf(Channel[cn-1].voc);
	Channel[cn-1].keynumber = 0;
	Channel[cn-1].lastkey = '\0';
	Channel[cn-1].keybuffer[0]    = '\0';	
}

/*************************************************************************
*   FUNC:	int  verify_the_key(int cn, THREAD * go_thread,  STATE * go_state)
*   
*	说明:	根据io参数表校验读键
*	参数:	cn = 通道号
*		go_thread = 键值有效的下一线程
*		go_state  = 键值有效的下一状态

⌨️ 快捷键说明

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