📄 voice.c
字号:
Sleep(100);
}
}
}
/****************************************************************
* Name : ChannelInit
* Input Parms : channel Number
* Description : Initialize channel status flags
* :
*****************************************************************/
int ChannelInit(int chNum)
{
char str[100];
TV_HangUpCtrl(chNum); //设通道为挂机状态
chInfo[chNum].status = C_FREE; //置空标记
chInfo[chNum].working= 0; //当前通道没有服务进程在工作
wsprintf(str,"Chan: %d initialized,wait for calling",chNum);
SendMessage(hChannelWnd,LB_ADDSTRING, //在通道信息窗口添加通道信息
0,(LPARAM) (LPCSTR)str);
wsprintf(str,"Channel %d initialized,now C_FREE",chNum); //在系统信息窗口显示信息
Msg_display(str);
return(TRUE);
}
/****************************************************************
* Name : WorkThread
* Input Parms : channel Number
* Description : Start check current channel event
* :
*****************************************************************/
DWORD WINAPI WorkThread(int *ch)
{
int m;
TV_Event event;
while( 1 )
{
m = TV_WaitForEvent(*ch,2000,&event);
//功能:通道等待事件函数,如果该通道调用此函数后,没有事件产生,则挂起,
//timeout秒后自动超时唤醒若有事件,则马上被唤醒,继续向后运行
if( m == 1 )
{
TV_GetEvent(*ch,&event); //从通道 ch中取事件至event结构中
CheckEvent(*ch,event); //在状态迁徙图检查并处理预定义事件
}
}
return(TRUE);
}
/****************************************************************
* Name : CheckEvent
* Input Parms : channel Number
* Description : 检查事件的启动对应处理流程
* :
*****************************************************************/
int CheckEvent(int ch,TV_Event event)
{
int i,m;
int n = -1;
int (*func_ptr)(int,TV_Event); //声明事件迁徙图中预定义的函数的结构
for(i=0; i<TABLE_SIZE; i++)
{
if(table[i].current_state == chInfo[ch].status //将该通道目前的状态和截获的事件类型,与事件迁徙表数据逐一对比
&& table[i].event == event.Type)
{
chInfo[ch].status = table[i].next_state; //找到对应数据时,首先该将通道状态设为下一状态
func_ptr = table[i].funcptr;
m = (*func_ptr)(ch,event); //执行预定义事件处理流程
n = 1; //标签
break;
}
}
return n; //处理了该事件,返回1,反之返回-1
}
/****************************************************************
* Name : ProcRing
* Input Parms : channel Number,channel event
* Description : 振铃事件处理流程
* :
*****************************************************************/
int ProcRing(int ch,TV_Event event) //振铃事件处理流程
{
char str[100];
wsprintf(str,"Channel %d ringing %d times",ch,event.Result);
Msg_display(str);
if( event.Result >=1 ) //响第一声铃后开始,准备服务处理
{
// TV_OffHookCtrl(ch);
// TV_SetMonitorCalled(ch,RECIEVEDIAL);
/*------------------------------------------------------------------
* 功能:在事件触发模式中,当通过拨号方式呼叫对方后,应立即调用此函数,对相应通道设置检测被呼叫方的状态标记,这样系统将用事件的方式告知被呼叫状态:摘机, 没人,忙音
* 参数:
* 1 ch:通道号
* Flag:检测选择标记
AFTERDIAL ---> 当主叫方,拨号后,必须调用此函数,对被叫方
状态进行检测。
RECIEVEDIAL --> 当被叫方检测到振铃,摘机后处于通话状态
时,需调用此函数,对主叫方是否挂机做检测。
* 返回:无意义
-----------------------------------------------------------------------*/
chInfo[ch].status = C_SERVICE;
}
return(TRUE);
}
/****************************************************************
* Name : ProcStartService
* Input Parms : channel Number,channel event
* Description : 开始启动服务子进程
* :
*****************************************************************/
int ProcStartService(int ch,TV_Event event) //振铃事件处理流程(二)
{
char str[100];
if( (event.Result >=2) && (chInfo[ch].working == 0)) //响第二声铃后开始,,开设子进程
{
chInfo[ch].status = C_SERVICE; //改写通道状态
//取主叫号
TV_ReceiveCallingID(ch,Channel_info[ch].CallerNum,MAX_CALLINGID_LEN);
//取呼入时间
_strdate( Channel_info[ch].InDate ); //model of 05/03/94
_strtime( Channel_info[ch].InTime ); //model of 21:51:03
//在这里改写、添加,通道&系统信息窗口内容
wsprintf(str,"Chan: %d %15s %12s has been in services since %9s",
ch,Channel_info[ch].CallerNum,"CalledNum",Channel_info[ch].InTime);
//model of: "Chan: 5 13320291670 66668888 have been in services since 21:51:03"
Channel_Msg_display(ch,str);
//在这里开始启动服务子进程
startin[ch].cb = sizeof(STARTUPINFO);
startin[ch].lpReserved = NULL;
startin[ch].lpDesktop = NULL;
startin[ch].lpTitle = NULL;
startin[ch].dwFlags = STARTF_USESHOWWINDOW;
startin[ch].cbReserved2 = 0;
startin[ch].lpReserved2 = NULL;
startin[ch].wShowWindow = SW_SHOWMINIMIZED;
_ProcessServiceID[ch] =
CreateProcess(NULL,
"Child.exe", //具体进程名
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&startin[ch],
&prinfo[ch]);
//-----------------------------
//
// 系统提示:
// 在判断振铃前,该外线通道应处于挂机状态。另外,由于振铃信号是断续的,
// 这样,振铃信号停止后的一小段时间内也可能检测到振铃信号,
// 应用程序中要考虑这种情况。一次振铃结束后振铃次数加一。
//
// 我处理方法:
// 第二声铃响,立即启动子进程,以后的响铃,不预理睬
// 但这里遗留了一个问题:系统是否能准确的截获到第二声的响铃呢?
// 所以,只好给每个通道打标chInfo[ch].working 见CHANNELINFO结构
//
//------------------------------
Sleep(100);
if(_ProcessServiceID[ch])
{
PostThreadMessage((DWORD)(prinfo[ch].dwThreadId),WM_COMMAND,(WPARAM) 19790917,(LPARAM) ch);
chInfo[ch].working= 1; //当前通道服务进程开始工作
}
}
return(TRUE);
}
/****************************************************************
* Name : ProcHangUp
* Input Parms : channel Number,channel event
* Description : 挂机事件处理流程
* :
*****************************************************************/
int ProcHangUp(int ch,TV_Event event) //通道(用户)挂机事件处理流程
{
char str[100];
if( event.Type == TEvent_HangUp)
{
chInfo[ch].status = C_FREE; //将通道状态置空闲
chInfo[ch].working= 0; //当前通道没有服务进程在工作
TV_HangUpCtrl(ch); //设置通道挂机
if(_ProcessServiceID[ch])
{
CloseHandle(prinfo[ch].hThread);
CloseHandle(prinfo[ch].hProcess);
}
// if(!GetExitCodeProcess(prinfo[ch].hProcess,0))
// TerminateProcess(prinfo[ch].hProcess,0); //终止为当前通道服务的子进程
//取挂机时间
_strdate( Channel_info[ch].EndDate ); //model of 05/03/94
_strtime( Channel_info[ch].EndTime ); //model of 21:51:03
//在这里改写、添加,通道&系统信息窗口内容
wsprintf(str,"Chan: %d %15s %12s has been hangup since %9s",
ch,Channel_info[ch].CallerNum,"CalledNum",Channel_info[ch].EndTime);
//model of: "Chan: 5 13320291670 66668888 have been in services since 21:51:03"
Channel_Msg_display(ch,str);
//-----------------------------
//在这里添加处理写记录的程序段
}
return(TRUE);
}
/****************************************************************
* Name : Refrush_Service
* Input Parms : none
* Description : Refrush service lists
* :
*****************************************************************/
void Refrush_Service(void)
{
char str[MAXSIZE];
char QueryStr[MAXSIZE];
MYSQL mysql;
MYSQL_RES *result;
MYSQL_ROW row;
unsigned int j=0;
if(!mysql_init(&mysql)){
MessageBox(MainhWnd,"内存不足,无法初始化连接数据库。",TEXT("致命错误"),MB_OKCANCEL);
SendMessage(MainhWnd,WM_DESTROY,0,0L);
}
mysql_options(&mysql,MYSQL_OPT_COMPRESS,0);//不使用 使用压缩的客户机/服务器协议
if (!mysql_real_connect(&mysql,system_db.DB_SERVER,system_db.DB_USER,system_db.DB_PWD,system_db.DB_DATABASE,system_db.DB_port,system_db.DB_unix_socket,system_db.DB_client_flag))
{
wsprintf(str, "Failed to connect to database: Error: %s",
mysql_error(&mysql));
Msg_display(str);
MessageBox(MainhWnd,str,TEXT("致命错误"), MB_OK );
SendMessage(MainhWnd,WM_DESTROY,0,0L);
}
else
{
wsprintf(str, "Current Mysql verion : Ver %s",
mysql_get_server_info(&mysql));
Msg_display(str);
}
wsprintf(QueryStr,"%s%d","SELECT MsgNum , ProgName , ProgType , FeeRate , MaxTime , ProgEXE , WorkPath , Para1 , Para2 , Para3 , ProvideTxt , Services FROM service WHERE 1 AND Services = 1 LIMIT 0 , ",MAXSERVICENUM);
if(mysql_real_query(&mysql,QueryStr,200))//如果查询成功,零。如果发生一个错误,非零
{
wsprintf(str, "查询系统服务信息库时发生一个错误: Error: %s",
mysql_error(&mysql));
Msg_display(str);
MessageBox(MainhWnd,str,TEXT("致命错误"), MB_OK );
mysql_close(&mysql);//关闭连接
SendMessage(MainhWnd,WM_DESTROY,0,0L);
}
result = mysql_store_result(&mysql);
if(!result){//指向一个结果集合 出现一个错误,NULL
wsprintf(str, "查询系统服务信息库时发生一个错误: Error: %s",
mysql_error(&mysql));
Msg_display(str);
MessageBox(MainhWnd,str,TEXT("致命错误"), MB_OK );
mysql_free_result(result);
mysql_close(&mysql);//关闭连接
SendMessage(MainhWnd,WM_DESTROY,0,0L);
}
else{
ServiceNum = (int) mysql_num_rows(result);//有效服务信息记录数,全局记录
wsprintf(str,"Service list have %d rows.", ServiceNum);
Msg_display(str);
}
while ((row = mysql_fetch_row(result)))
{
strcpy(Service_info[j].MsgNum,row[0] ? row[0] : "NULL");
strcpy(Service_info[j].ProgName,row[1] ? row[1] : "NULL");
Service_info[j].ProgType = atol(row[2]);
Service_info[j].FeeRate = atol(row[3]);
Service_info[j].MaxTime = atol(row[4]);
strcpy(Service_info[j].ProgEXE,row[5] ? row[5] : "NULL");
strcpy(Service_info[j].WorkPath,row[6] ? row[6] : "NULL");
strcpy(Service_info[j].Para1,row[7] ? row[7] : "NULL");
strcpy(Service_info[j].Para2,row[8] ? row[8] : "NULL");
strcpy(Service_info[j].Para3,row[9] ? row[9] : "NULL");
strcpy(Service_info[j].ProvideTxt,row[10] ? row[10] : "NULL");
Service_info[j].Services= atol(row[11]);
j++;
}
mysql_free_result(result);
mysql_close(&mysql);
}
/****************************************************************
* Name : ExitSys
* Input Parms : None.
* Description : ExitSys
* :
*****************************************************************/
void ExitSys()
{
int i;
for(i=0; i<MAXCHANNEL; i++)
{
TerminateThread(workHandle[i],1);
if( workHandle[i] )
CloseHandle(workHandle[i]);
}
TV_Disable();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -