📄 d300.cpp
字号:
#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 + -