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

📄 voice.c

📁 五岳鑫电话卡应用开发
💻 C
📖 第 1 页 / 共 3 页
字号:
			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 + -