📄 d300.cpp
字号:
dt_settssigsim(Channel[i].dti,DTB_AON|DTB_BOFF|DTB_CON|DTB_DON);
//接收信号事件,对于SC设备 AON和AOFF同时要设置。
if(dt_setevtmsk(Channel[i].dti,DTG_SIGEVT,DTMM_AON|DTMM_AOFF,DTA_SETMSK)==-1){
WinPrintf("%s: dt_setevtmsk()\n",Channel[i].dtiname);
exit(1);
}
//printts(i+1);
ChnPrintf(i+1, "_STATE", "空闲");
count ++;
} // for i=0 to System.ChannelNumber
SysPrintf("Channels open successfully!", count);
return 0;
}
/******************************************************************************
* 函数: int chan_init(int i)
*
* 描叙: 设置DTI通道为初始态
* 参数: channel NUMBER
* 返回值: 0 成功
* -1 失败
******************************************************************************/
int chan_init(int i)
{
//if(DEBUG) WinPrintf("%s: In chan_init()\n",Channel[i].voxname);
strcpy(Channel[i].dnis,"");
strcpy(Channel[i].ani,"");
Channel[i].number=0;
dt_settssigsim(Channel[i].dti,DTB_AON|DTB_BOFF|DTB_CON|DTB_DON);
return 0;
}
/******************************************************************************
* Name: printts()
* Function: 显示 RX 和 TX 字节
*
******************************************************************************/
int printts(int cn)
{
int i= cn-1;
int err;
long tsbits;
int arcv,brcv,crcv,drcv,axmt,bxmt,cxmt,dxmt;
if((tsbits=ATDT_TSSGBIT(Channel[i].dti))==AT_FAILURE){
err = ATDV_LASTERR(Channel[i].dti);
WinPrintf("ATDT_TSSGBIT() Error message =%s",ATDV_ERRMSGP( Channel[i].dti));
return -1;
}
arcv=(tsbits & DTSG_RCVA)?1:0;
brcv=(tsbits & DTSG_RCVB)?1:0;
crcv=(tsbits & DTSG_RCVC)?1:0;
drcv=(tsbits & DTSG_RCVD)?1:0;
axmt=(tsbits & DTSG_XMTA)?1:0;
bxmt=(tsbits & DTSG_XMTB)?1:0;
cxmt=(tsbits & DTSG_XMTC)?1:0;
dxmt=(tsbits & DTSG_XMTD)?1:0;
ChnPrintf(cn, "_STATE","RX=%d%d%d%d,TX=%d%d%d%d,TRD=%d",arcv,brcv,crcv,drcv,axmt,bxmt,cxmt,dxmt,Channel[i].thread_id);
return 0;
}
/*************************************************************************
* 函数 : open_all_voc_file()
* 描叙 : 打开VFIT中列出的所有语音文件,并将语音句柄保存在VFIT结构中。
*
* 参数 : 无
* 返回 : 打开的文件数
*************************************************************************/
int open_all_voc_file(void)
{
int i;
char count[10], shandle[20];
int fhandle;
char filename[160];
int openfile=0;
for(i=0; i<System.VFITNumber; i++)
{
itoa(i,count,10);
if (openfile <1){
strcpy(filename, System.voxpath);
strcat(filename, Vfit[i].vocfile);
fhandle=dx_fileopen(filename,O_RDONLY|O_BINARY);
if(fhandle<=0){
SysPrintf("语音文件 %s 打开失败.", filename);
return i-1;
}
}
openfile = 1;
itoa(fhandle,shandle,10);
strcpy(Vfit[i].filehandle, shandle);
}
System.VocNumber = i;
return i-1;
}
/*************************************************************************
* 函数 : close_all_voc_file()
* 描叙 : 关闭VFIT中列出的所有语音文件。
*
* 参数 : 无
* 返回 : 打开的文件数
*************************************************************************/
int close_all_voc_file(void)
{
int number,i;
char snum[10];
char count[10], sfh[80];
int fhandle;
//系统语音文件数
strcpy(snum,(const char *)ReadGCA("VFIT_LEN"));
number = atoi(snum);
for(i=1; i<=number; i++)
{
itoa(i,count,10);
strcpy(sfh, (const char *)ReadVFIT(count,"filehandle"));
fhandle = atoi(sfh);
dx_fileclose(fhandle);
SetVFIT(count, "filehandle", "");
}
SysPrintf("Vox file closed.");
return i-1;
}
/*******************************************************************************
* Name : close_channel(int chn)
* Input: 通道号 ( chn = 1...MAXCHAN )
* Des: 关闭语音卡,关闭所有文件。
*
*******************************************************************************/
int close_channel(int chn)
{
dx_stopch(Channel[chn-1].voc,EV_ASYNC);
dx_close(Channel[chn-1].voc);
dt_close(Channel[chn-1].dti);
return 0;
}
/*************************************************************************
* 函数 : set_system_info()
* 描叙 : 设置程序的共享信息
*
*************************************************************************/
int set_system_info(void)
{
char vox_path[160];
char startmonth[10], endmonth[10], qftable[10];
System.SysThreadNumber = 0;
System.ChannelNumber = 0;
System.VocNumber = 0;
strcpy(vox_path,(const char *)ReadGCA("vox_path"));
strcat(vox_path,"\\");
strcpy(System.voxpath, vox_path);
//将VFIT复制到本地
CopyVFIT();
//查询起始月
strcpy(startmonth, (const char *)ReadGCA("StartQueryMonth"));
System.QueryMonthStart = atoi(startmonth);
strcpy(endmonth, (const char *)ReadGCA("EndQueryMonth"));
System.QueryMonthEnd = atoi(endmonth);
//当前欠费表
//strcpy(qftable, (const char *)ReadGCA("CurQfTable"));
System.CurQfTable = 1;
//复制拒绝号码表
CopyRefuseCall();
//复制查询语法区
CopyRefuseQSSA();
return 0;
}
/*************************************************************************
* 函数 : init_prog()
* 描叙 : 应用初始化,初始化数据结构
*
*************************************************************************/
int init_prog(void)
{
init_30();
init_voice();
open_all_voc_file();
return 1;
}
/*******************************************************************************
* Name : end_prog()
* Input: none.
* Des: 关闭语音卡,关闭所有文件。
*
*******************************************************************************/
int end_prog()
{
int cn;
SysPrintf(" ");
//SysPrintf("语音受理程序 shutdown ...");
if (System.SysThreadNumber > 0 ){
//终止事件分发线程
SysThread[_dispatcher].keep_running = false;
//终止Time Triiger线程
SysThread[_timetrigger].keep_running = false;
//为避免线程阻塞,发一个消息
for (cn=1; cn<=MAXCHAN; cn++)
{
if (Channel[cn-1].SeizedByThisApp)
{ put_event_to_board(cn, sys_exit);
break;
}
}
//等待线程结束
::WaitForSingleObject(System.AllThreadClosed.m_hObject, INFINITE);
//关闭被程序占用的通道
for(cn=1;cn<=MAXCHAN;cn++){
if (Channel[cn-1].SeizedByThisApp){
close_channel(cn);
}
ChnPrintf(cn,"_USER", " ");
ChnPrintf(cn,"_STATE"," ");
ChnPrintf(cn,"_TELE", " ");
}
SysPrintf("所有通道已关闭.");
//关闭语音文件
close_all_voc_file();
}
SysPrintf("语音受理程序退出 !");
SysPrintf(" ");
return 0;
}
/*************************************************************************
* FUNC: sys_event_dispatcher()
*
* 说明: 系统事件分发器
*
* 该函数监控所有语音卡通道,然后根据将事件转发到工作线程上。
*
************************************************************************/
UINT sys_event_dispatcher(LPVOID pParam)
{
bool myDEBUG = false;
long Dev[MAXCHAN*2];
int i, j=0;
int result,cn;
long ehandle; //事件句柄
long dev_handle; //设备句柄
//系统线程
System.SysThreadNumber ++;
//判断那些通道被本程序占用
for (i=0; i<MAXCHAN; i++)
{
if (Channel[i].SeizedByThisApp){
Dev[j++] = Channel[i].voc;
Dev[j++] = Channel[i].dti;
}
}
while (SysThread[_dispatcher].keep_running)
{
result = sr_waitevtEx(Dev, j, -1, &ehandle);
if ((dev_handle = sr_getevtdev(ehandle)) == -1) continue;
/* { 根据设备句柄判断通道号 cn } */
for (i=0,cn=0; i<MAXCHAN && cn==0; i++)
{
if (dev_handle==Channel[i].voc || dev_handle==Channel[i].dti){
cn = i+1;
}
}
if (cn==0) continue;
//将事件数据保存在通道结构中
Channel[cn-1].evt_handle = ehandle;
Channel[cn-1].dev_handle = dev_handle;
Channel[cn-1].wait_result = result;
/* 线程模式时使用事件消息模式
//向通道 cn 的 StartWork 发 Signal
Channel[cn-1].startwork.SetEvent();
*/
switch (Channel[cn-1].thread_id){
case _main:
main_thread_func(cn);
break;
case _singleinput:
singleinput_thread_func(cn);
break;
case _monthinput:
monthinput_thread_func(cn);
break;
case _multiplay:
multiplay_thread_func(cn);
break;
case _timeout:
timeout_thread_func(cn);
break;
default: WinPrintf("sys_event_dispatcher: invalid Channel[cn-1].thread_id=%d",Channel[cn-1].thread_id);
break;
}
} // while (SysThread[_dispatcher].keep_running) .
--System.SysThreadNumber;
SysPrintf("System Event Dispatcher 退出");
if (System.SysThreadNumber == 0) {
System.AllThreadClosed.SetEvent();
}
return 0;
}
/*************************************************************************
* FUNC: main_thread_func()
*
* 说明: 主线程控制函数
*
*
************************************************************************/
UINT main_thread_func(int cn)
{
bool myDEBUG = false;
DX_CST * cstp;
int result;
long evt_handle; //事件句柄
int EventType; //事件类型
long dev_handle; //设备句柄
int count=0;
int ret;
char sdatetime[128];
result = Channel[cn-1].wait_result;
evt_handle = Channel[cn-1].evt_handle;
dev_handle = Channel[cn-1].dev_handle;
//获取事件类型
EventType = sr_getevttype(evt_handle);
switch(EventType){
case DTEV_SIG: //DTI 上的信号事件,datap是事件的bitmask(ABCD);
check_commu_status(cn,evt_handle);
break; // break case DTEV_SIG
case TDX_CST: //Vocie上的状态事件
if(myDEBUG) SysPrintf("%s: EVENT TYPE: TDX_CST\n",Channel[cn-1].voxname);
cstp=(DX_CST*)sr_getevtdatap(evt_handle);
switch (cstp->cst_event){
case DE_TONEON:
//主叫传送中...
dti_read_ani(cn);
break;
case DE_TONEOFF:
break;
case ani_recieve:
//主叫接收
ChnPrintf(cn,"_STATE","通话建立");
get_system_datetime(sdatetime);
ChnPrintf(cn,"_BEGIN", sdatetime);
ChnPrintf(cn,"_TELE",Channel[cn-1].ani);
Channel[cn-1].Main.cur_st= verify_ani;
//效验主叫
ret = DoVerifyAni(Channel[cn-1].ani);
if (ret==1){
put_event_to_board(cn, ani_valid);
}else{
put_event_to_board(cn, ani_invalid);
}
break;
case ani_valid: //主叫有效
Channel[cn-1].ServerLog.WriteLog = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -