/*************************************************
File name:	omcMain.c
Author: 	Cui Ticun
Version:	9.00.00 
Date:  		2007-8-1
Description:It calls the plat Module:SNMP,MTP3,SCCP,DEBUG,SMPP
				 and the faultMgr	:beatSend,beatProc,dualSrv
						
History:               
No. 
Author  
Date    
Version   
Description
*************************************************/

#include "omcMain.h"

extern  int iptrans_init();
extern void WriteParalPort(u8 flag,u8 data);
extern void InitParalPort();
extern int dualsrv_init();
extern int dualsrv_timer();
extern void smeg_init(BYTE *sequenceNum, int sysNo,int subSysNo,int license);
extern void smeg_main();
extern int getOmcSN();
void writeDebug(const char *fmt, ...);
void onOmcMainTimer();
void setOmcMainTimer();
void setup_daemon(void);
int getOmcConf();
void ReadSystemConf();
static int CheckHDLicense(unsigned char *HDSerialNumber);
static int CheckLicenseDate(const u_char license_date[3]);

static void wxc2SetTermSignal(struct termio *ptermio, void (*handler)(int));
static void wxc2Terminate(int sig);

static struct itimerval itimer,old_itimer;
unsigned long timerCount=1;
unsigned long beatSendOldTimeStamp;
unsigned long beatProcOldTimeStamp;
int		omcTypeNo,omcSysNo,omcSubSysNo;
char	omcVersion[16];
int		omcRunMode=0;
unsigned char LED0=0;//程序正常运行过程中，以1Hz的频率闪烁，亮灯时间为500ms
unsigned char LED1=0;//标注OMC是否有告警,亮灯时表示有告警
unsigned char LED2=0;//当系统有双平面时，用来指示系统ID：系统master=常亮 ； 系统salve=常灭
unsigned char LED3=0;//以50Hz的频率闪烁，亮灯时间为平台模块所占时间
unsigned char LED4=0;
unsigned char LED5=0;
unsigned char LED6=0;
unsigned char LED7=0;

/* by simon at 23/9/27 */
int corefile_flag = 0;

//for beatSend
omcBaseInfo omcInfo;

static char tmpSequenceNumber[18]="";
BYTE sequenceNum[4]={19,117,0,21};

#define MAX_APP_NUM		16
#define MAX_LICENSE_TYPE	255

enum _SYS_LIST{
	MSC_,
	HLR_,
	VLR_,
	AUC_,
	EIR_,
	PPS_,
	SMSC_,
	MNPF_,
	SMEG_,
};


/*index=MSC,HLR,PPS,AUC,EIR ,from 0 */

typedef struct _wxc2_param_old
{
   int  segmentFaultAction;
   char segmentFaultCommand[128];
   int  register_flag[MAX_APP_NUM];
   int  max_users[MAX_APP_NUM];
   char serialNumber[16];
   char HDSerialNumber[256];
}wxc2_param_old;


//struct _wxc2_param
//{
//	char serialNumber[16];
//	int systemType;
//	int register_flag[MAX_APP_NUM];
//	int max_users[MAX_APP_NUM];
//	unsigned char HDSerialNumber[2][256];
//	unsigned char userBcdLicense[MAX_LICENSE_TYPE][8];
//	unsigned int userIntLicense[MAX_LICENSE_TYPE];
//	u_char license_date[3]; /* year(0-99),month,day */
//}wxc2_param,tmpParam;

struct _wxc2_param
{
	char serialNumber[16];
	int systemType;
	u_char license_date[3]; /* year(0-99),month,day */
	int register_flag[MAX_APP_NUM];
	int max_users[MAX_APP_NUM];
	unsigned char HDSerialNumber[2][256];
	unsigned char userBcdLicense[MAX_LICENSE_TYPE][8];
	unsigned int userIntLicense[MAX_LICENSE_TYPE];
}wxc2_param,tmpParam;

int main(int argc,char *argv[])
{	
	char runOption;
	char buf[32]="";
	char tmpStr[4];
	int tmpValue;
	int i;
	int sysCode;
	struct termio prev_termio;
	unsigned char smegLicense[8];
	pid_t pid;
	char message[512];

	memset(omcVersion, 0, 16);
	writeDebug("Program is starting ...\n");
	
	runOption =getopt(argc,argv,"d");
	if(getOmcConf() <= 0){
		fprintf(stderr,"\nCan not read parameter from omcd.conf.\n ");
		writeDebug("Can not read parameter from omcd.conf.\n");
		return(0);
	}
	/* merge by simon, 2023/11/02, begin ===*/
	if (getOmcSN() <= 0)
	{
		fprintf(stderr, "\nCan not read parameter from omcd_serialnum.conf.\n ");
		writeDebug("Can not read parameter from omcd_serialnum.conf.\n");
		return (0);
	}
	/* merge by simon, 2023/11/02, end ===*/

	/**********Get serial/sequence Number*********/
	// snmp_set_timesync(0);//call of this function will tell snmp module do not sync the omc time
	ReadSystemConf();

	// fj added 2020-01-18
	// 设置要不要检测license
#if (HD_SN_CHECK_FLAG == 1)
	if(!CheckHDLicense(wxc2_param.HDSerialNumber[0]))
	{
		fprintf(stderr,"Wrong FIB file: Hardware codeis not correct.\n");
		writeDebug("Wrong FIB file: Hardware codeis not correct.\n");
		return(0);
	}
	// fj added. add check license date
	if(!CheckLicenseDate(wxc2_param.license_date))
	{
		fprintf(stderr,"License is out of date.\n");
		writeDebug("License is out of date.\n");
		return(0);
	}

	AsciiToBcd((BYTE*)buf,wxc2_param.serialNumber,16); 
	// removed by simon, 2023/11/02
	//DesCrypt((BYTE*)tmpSequenceNumber,(BYTE*)buf,NULL,1);
	
	DesCrypt(smegLicense,wxc2_param.userBcdLicense[SMEG_],NULL,1);
	wxc2_param.userIntLicense[SMEG_] = (smegLicense[6] * 256 + smegLicense[7])*100;
#endif

	//printf("smegLicense[6]=%d,smegLicense[7]=%d\n", smegLicense[6], smegLicense[7]);

	if(wxc2_param.userIntLicense[SMEG_]>50000||wxc2_param.userIntLicense[SMEG_]<0)
		wxc2_param.userIntLicense[SMEG_]=10000;
	printf("smegLicense=%d\n",wxc2_param.userIntLicense[SMEG_]);

	for(i=0;i<4;i++){
		//High 4 bit
		tmpStr[0]=tmpSequenceNumber[i*2+0];
		tmpStr[1]=0;
		tmpValue=atoi(tmpStr)<<4; 
		//low 4 bit;
		tmpStr[0]=tmpSequenceNumber[i*2+1];
		tmpStr[1]=0;
		tmpValue=tmpValue+atoi(tmpStr);
		sprintf(message, "tmpValue=%d\n", tmpValue);
		writeDebug(message);
		sequenceNum[i]=tmpValue;
	}

	printf("SequenceNumber:");
	sprintf(message,"SequenceNumber=");
	for(i=0;i<4;i++)
	{
		printf("%02X,",sequenceNum[i]);
		sprintf(tmpStr,"%02X",sequenceNum[i]);
		strcat(message,tmpStr);
	}
	strcat(message,"\n");
	writeDebug(message);
	printf("\n");
	/**********Get serial/sequence Number End*********/
	
	if (argc == 2 && strstr(argv[1], "-d")) {
		if ((pid = fork()) != 0)
			exit(0);
		setsid();
		//umask(0);
	}
/*	switch(runOption){
		case 'd': 
			setup_daemon();
			break;
		case '?':
			break;
	}*/
	
	debug_init();//must do it at first
	sysCode = omcSysNo*omcMaxSubSysNum+omcSubSysNo;
	
	// by simon at 20240426
	//init red led,set it to off
	//WriteParalPort(0,1);
	//init p1& p16
	//outb(0x05,PORT);
	// -- end by simon
	
	fprintf(stderr,"\n Calling heartbeat_init(%x) finished",sysCode);
	heartbeat_init(sysCode);
	fflush(NULL);

	fprintf(stderr,"\n Calling iptrans_init()");
	iptrans_init();
	fflush(NULL);

	fprintf(stderr,"\n Calling mtp_shm_init()");
	mtp_shm_init(0);
	mtp3_init_serial(tmpSequenceNumber);	
	fflush(NULL);

	fprintf(stderr,"\n Calling sccp_init()");
	sccp_init();
	sccp_init_serial_number(tmpSequenceNumber);
	fflush(NULL);

	fprintf(stderr,"\n Calling beatProcInit()");

	beatProcInit(sequenceNum);
	fflush(NULL);

	fprintf(stderr,"\n Calling beatSendInit()");
	omcInfo.omcTypeNo	=omcTypeNo;
	omcInfo.sysNo		=omcSysNo;
	omcInfo.subSysNo	=omcSubSysNo;
	omcInfo.runMode		=omcRunMode;
	memcpy(omcInfo.version,omcVersion,sizeof(omcVersion));

	beatSendInit(&omcInfo,sequenceNum);
	fflush(NULL);

	fprintf(stderr,"\n Calling smpp_init_new()");
	smpp_init_new(sysCode);
	fflush(NULL);
	
	//Init raid agent
	raid_agent_init(omcSysNo);

	fprintf(stderr,"\n Calling smeg_init()");
	smeg_init(sequenceNum,omcSysNo,omcSubSysNo,wxc2_param.userIntLicense[SMEG_]);
	fflush(NULL);

	fprintf(stderr,"\n Calling wsms_init()");
	wsms_init();
	fflush(NULL);

	if( omcRunMode == 0){
		register_ssn(4,1);
	}
	
	//fprintf(stderr,"\n Calling cstaCollector_init()");
	//csta_init(); 
	
	fprintf(stderr,"\n Calling init_paralport()");
	InitParalPort();

	//if( omcRunMode == 1){
		fprintf(stderr,"\n Calling dualsrv_init()");
		dualsrv_init();
	//}

	snmp_init(4957);
	snmp_init_serial_number((BYTE*)tmpSequenceNumber);
	
	printf("\n Finish all module's init!!");

	wxc2SetTermSignal(&prev_termio,wxc2Terminate);		
	setOmcMainTimer();
	while(1)
	{
		usleep(2000);
	}
	return(1);
}

void onOmcMainTimer(){
	BYTE			m_state = 0;
	unsigned long	newTimeStamp;
	static int		shutSigCont=0;
	static int 		reloadFlag=0;
	
//START;
	
	if(reloadFlag==1){//Prevent to omcMainTimer reload
	 	// removed by simon, 2023/11/02
		//printf("Has prevented to onOmcMainTimer reload\n");
		return;
	}

	reloadFlag=1;

	//当0x379被连续按住超过10秒时，系统关机（LINUX服务器）
	//by simon at 20240426
//	if(~(inb(0x379)) & 0x10){
/*		if(shutSigCont++ > 500){// 10s
			int i;
			for(i=1;i<10;i++){
				WriteParalPort(i,0);//set green led to off
			}
			WriteParalPort(0,1);//set red led to off
			system("poweroff");
			exit(0);
		}
*/ //	}else{
	 //	shutSigCont = 0;
	 //}
	 // end by simon
	
	//init red led,set it to off
	WriteParalPort(0,1);
	newTimeStamp = time(NULL);
//END("process1");
	
//START;	
	#if omcMain_DEBUG
		printf("\n %lu ,begin",time(NULL));
	#endif

	//if( omcRunMode == 1){
		m_state=dualsrv_timer();
	//}
//END("dualsrv_timer");
	#if omcMain_DEBUG
		printf("\n %lu, dualsrv_timer()",time(NULL));
	#endif
//START;	
	WriteParalPort(5,1);
	LED3=1;
	debug_rt();
	mtp3_proc();
	sccp_timer();
	snmp_timer();
	heartbeat_timer();
	smpp_fsm_new();
	
	
	
	WriteParalPort(5,0);
	LED3=0;
//printf("omcMain timer,timerCount=%d\n",timerCount);
	if(timerCount % 100 == 0){ //1s
//printf("omcMain timer,omcRunMode=%d\n",omcRunMode);
		if(omcRunMode == 1){
//printf("call beatSend in omcMain, omcRunMode=1\n");
			LED1=beatSend(m_state,omcRunMode);
		}else{
//printf("call beatSend in omcMain, omcRunMode!=1\n");
//printf("beatSend %ld\n",time(NULL));
			LED1=beatSend(1,omcRunMode);
		}
		WriteParalPort(3,LED1);
		beatSendOldTimeStamp = newTimeStamp;
	}
	
	if((timerCount % 5 == 0) || (abs(newTimeStamp - beatProcOldTimeStamp) > 1)){ //100ms or 1s
		beatProc();
		if(timerCount % 25 == 0){
			if(LED0 == 0){
				WriteParalPort(2,1);
				LED0=1;
			}else{
				WriteParalPort(2,0);
				LED0=0;
			}
		}
		if((omcRunMode == 0) || (m_state > 0)){ //master
			WriteParalPort(4,1);
		}else{
			WriteParalPort(4,0);	
		}
		beatProcOldTimeStamp = newTimeStamp;
	}
	
	if((omcRunMode == 0) || (omcRunMode == 1&& m_state == 0)){ 
		if(timerCount % 5 == 0){ 
			smeg_main();
		}	
	}
	raid_agent_timer();
	wsms_timer();
	//if((omcRunMode == 0) || (m_state > 0)){ //master
		//csta_timer();		
		//wsms_timer();
		//cdr_timer();
		//WriteParalPort(9,0);
	//}else{
		//snmp_set_timesync(1);//call of this function will tell snmp module sync the omc time from the master omc
//		WriteParalPort(9,1);
	//}

	if(timerCount > 180000){ //one hour's timerCount
		timerCount=0;
	}
	timerCount++;
	reloadFlag=0;
//END("other");
}


void setOmcMainTimer()
{
	struct sigaction	act;
	act.sa_handler=onOmcMainTimer;
	act.sa_flags=0;
	sigemptyset(&act.sa_mask);
	if(sigaction(SIGALRM,&act,NULL)<0)
	{
		perror("Produce Sigaction");
		exit(1);
	}
	
	itimer.it_interval.tv_sec=0;
	itimer.it_interval.tv_usec=10*1000;
	itimer.it_value.tv_sec=0;
	itimer.it_value.tv_usec=10*1000;

	if (setitimer(ITIMER_REAL,&itimer,&old_itimer) !=0 )
	{
		printf("Setting Timer  error! \n");
		exit(1);
	}
}

/*************************************************
Function:        // getOmcConf
Description:     // get omcVersion and omcBaseInfo from omcd.conf
Calls:           // 
Called By:       // main()
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 1:OK,-1:error
Others:          // 
*************************************************/
int getOmcConf()
{
	int statfd;
	int i=0,buffSize = 1024;
	char buff[buffSize];
	char strBuf[64];
	char *tmpStr;
   	char *b=NULL;
	char *oneNum=NULL;
	if ((statfd = open(OMCD_CONF_FILE, O_RDONLY, 0)) != -1){
		buff[buffSize-1] = 0;
		read(statfd, buff, buffSize-1);
		close(statfd);

		b = strstr(buff, "omcVersion=");
		if(b == NULL){
			fprintf(stderr,"[%s:%d] %s Error: Cannot get omcVersion!! \n",__FILE__,__LINE__,__FUNCTION__);
			exit(1);
		}else{
			sscanf(b, "omcVersion=%s \n", strBuf);
			printf("omcVersion=%s \n",	strBuf);
		}
		tmpStr=strBuf;
		i = 0;
		while((oneNum = strsep(&tmpStr, "."))){
			if(atol(oneNum) >= 0xFF || i >= 3){
				fprintf(stderr,"[%s:%d] %s Error: OMC Version is error!! \n",__FILE__,__LINE__,__FUNCTION__);
				exit(1);
			}
			omcVersion[i]	= atol(oneNum);
			//printf("omcVersion[%d]=%d \n",i,omcVersion[i]);
			i++;
		}

		b = strstr(buff, "omcTypeNo=");
		if(b == NULL){
			printf("Cannot get omcTypeNo!! \n");
			exit(1);
		}else{
			sscanf(b, "omcTypeNo=%d \n", &omcTypeNo);
			printf("omcTypeNo=%d \n",omcTypeNo);
		}
		
		b = strstr(buff, "omcSysNo=");
		if(b == NULL){
			printf("Cannot get omcSysNo!! \n");
			exit(1);
		}else{
			sscanf(b, "omcSysNo=%d \n", &omcSysNo);
			printf("omcSysNo=%d \n",omcSysNo);
		}

		b = strstr(buff, "omcSubSysNo=");
		if(b == NULL){
			printf("Cannot get omcSubSysNo!! \n");
			exit(1);
		}else{
			sscanf(b, "omcSubSysNo=%d \n", &omcSubSysNo);
			printf("omcSubSysNo=%d \n",omcSubSysNo);
		}

		b = strstr(buff, "omcRunMode=");
		if(b == NULL){
			printf("Cannot get omcRunMode!! \n");
			omcRunMode=0;
			//exit(1);
		}else{
			sscanf(b, "omcRunMode=%d \n", &omcRunMode);
			printf("omcRunMode=%d \n",omcRunMode);
		}
		
		return(1);
	}else{
		fprintf(stderr,"[%s:%d] %s Error: Can not open config file:%s!! \n",__FILE__,__LINE__,__FUNCTION__,OMCD_CONF_FILE);
		return(-1);
	}
}

/*************************************************
Function:        // getOmcSN
Description:     // get omcSerialNum from omcd_serialNum.conf
Calls:           //
Called By:       // main()
Table Accessed:  //
Table Updated:   //
Input:           //
Output:          //
Return:          // 1:OK,-1:error
Others:          //
*************************************************/
int getOmcSN()
{
	int statfd;
	int buffSize = 1024;
	char buff[buffSize];
	char strBuf[64];
	char *tmpStr;
	char *b = NULL;
	memset(strBuf, 0, 64);
	memset(buff, 0, buffSize);
	if ((statfd = open("./conf/omcd_serialnum.conf", O_RDONLY, 0)) != -1)
	{
		buff[buffSize - 1] = 0;
		read(statfd, buff, buffSize - 1);
		close(statfd);

		b = strstr(buff, "omcSN=");
		if (b == NULL)
		{
			fprintf(stderr, "[%s:%d] %s Error: Cannot get omc sequence number!! \n", __FILE__, __LINE__, __FUNCTION__);
			exit(1);
		}
		else
		{
			sscanf(b, "omcSN=%s \n", strBuf);
			memcpy(tmpSequenceNumber, strBuf, 18);
			tmpSequenceNumber[8] = '\0';
			printf("omcSN=%s \n", strBuf);
			printf("tmpSequenceNumber=%s\n", tmpSequenceNumber);
		}

		return (1);
	}
	else
	{
		fprintf(stderr, "[%s:%d] %s Error: Can not open omcd_serialnum.conf !! \n", __FILE__, __LINE__, __FUNCTION__);
		return (-1);
	}
}

/*************************************************
Function:        // ReadSystemConf
Description:     // get serial/sequence numver from omcd.conf
				 //Check Activation_request_code.txt
Calls:           // 
Called By:       // main()
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void ReadSystemConf()
{
	FILE *fpConf=NULL;
	int i,flag=0;
 // char hostname[128];
	char filename[]="./conf/system.ini";
	struct stat fileinfo;
	//u_char data[8];
	
	fpConf = fopen(filename,"r");
	if(fpConf==NULL){
		printf("Cann't open config file\n");
		printf("Please check directory and conf file\n");
		printf("Failed to continue!\n");
		exit(1);
	}
	stat(filename,&fileinfo);
	/*
	if(fileinfo.st_size != sizeof(wxc2_param))
	{
		// don't set license when initialized
		//updateFromLowVersion = 1;
		//if(fileinfo.st_size == sizeof(wxc2_param_old))
		{
			wxc2_param_old tmpParam;
			fread(&tmpParam,sizeof(wxc2_param_old),1,fpConf);
			memcpy(wxc2_param.serialNumber,tmpParam.serialNumber,16);
			memcpy(wxc2_param.HDSerialNumber[0],tmpParam.HDSerialNumber,256);
		}
		
	}
	else	
	*/
		fread(&wxc2_param,sizeof(wxc2_param),1,fpConf);
	fclose(fpConf);

	/*
	if(updateFromLowVersion)
	{
		memcpy(wxc2_param.HDSerialNumber[1],wxc2_param.HDSerialNumber,256);
	}
	*/
	
	for(i=0;i<MAX_APP_NUM;i++){
		if(wxc2_param.register_flag[i])
			flag = 1;
	}
	/*
	wxc2_param.register_flag[2]=0;
	wxc2_param.register_flag[3]=0;
	wxc2_param.register_flag[4]=0;
	wxc2_param.register_flag[6]=0;
	*/
	/*
	if(flag==0) 
	{
		printf("Error config file for no application enabled!\n");
		exit(1);
	}*/
	/*
	if(wxc2_param.systemType == WXC2_SYSTYPE_UNIB)
	{
		plat_work_port = (MAX_DIALOGUEID/4);
		printf("system info: UNIB\n");
	}
	else if(wxc2_param.systemType == WXC2_SYSTYPE_X40)
	{
		plat_work_port = (MAX_DIALOGUEID/2);
		printf("system info: X40\n");
	}
	else
	{
		plat_work_port = MAX_DIALOGUEID;
		printf("system info: X100\n");
	}*/
	/* 
	if(!gethostname(hostname,128)){
		if(strstr(hostname,"-0")!=NULL){
		 systemID = 0;
		}else if(strstr(hostname,"-1")!=NULL){
		 systemID = 1;
		}
	}
	*/
	
	/*
	for(i=0;i<MAX_APP_NUM;i++){
		printf("APP[%d]:\n",i);
		printf("  register: %d\n",wxc2_param.register_flag[i]);
		printf("  max user: %d\n",wxc2_param.max_users[i]);
	}
	
	for (i = 0; i < MAX_FUNCTION_ID; i++)
	{
		if ((i < MAX_APP_FUNC_ID) && (wxc2_param.register_flag[i] == 0))
		{	// application, not registered
			wxc2_param.userIntLicense[i] = 0;
			printf("LICENSE[%d]:%d\n",i, wxc2_param.userIntLicense[i]);
			continue;
		}
		DesCrypt(data,wxc2_param.userBcdLicense[i],NULL,1);
		wxc2_param.userIntLicense[i] = (data[6] * 256 + data[7]) * wxc2_license_rule[i].step;
		printf("LICENSE[%d]:%d\n",i, wxc2_param.userIntLicense[i]);
	}*/
}

static int CheckHDLicense(unsigned char *HDSerailNumber)
{
	FILE *fpConf=NULL;
	int i,j=0,k;
	char ethmac[64],meminfo[64],cpuinfo[64],hwinfo[128],*offset,buf[2048];
	char	ascii_buf[256] = {0};
	unsigned char TmpStr[64] = {0}, act_req_code[128] = {0}, act_req_code_des[128] = {0};
	
	// add by simon, 2023/11/25
	struct sysinfo info;
	sysinfo(&info);
	long totalMemory = (info.totalram * info.mem_unit) / 1000 / 1000;
	writeDebug("info.totalram=%ld, info.mem_unit=%ld, totalMemory=%ld\n", info.totalram, info.mem_unit, totalMemory);

	//struct stat fileinfo;
	
	// Ethernet Hardware Address
	printf("Check HD license ...\n\n");
	 
	memset(ethmac, 0, 64);
	sprintf(buf,"ifconfig >../log/hwlog.txt");
	system(buf);
	fpConf = fopen("../log/hwlog.txt","r");
	if(fpConf != NULL)
	{
		fread(buf,2048,1,fpConf);
		offset = strstr(buf,"HWaddr ");
		if(offset ==  NULL)
			offset = strstr(buf,"ether ");
		
		if (offset != NULL)
		{
			offset += 7;
			for(i=0,j=0;i<64;i++)
			{
				if ((*(offset+i)=='\n') ||
					(*(offset+i)==' '))
				{
					ethmac[j] = 0;
					break;
				}
				else if (*(offset+i)==':')
					continue;
				else
				{
					ethmac[j] = *(offset+i);
					//printf("ethmac[%d] = %c\n", j, ethmac[j]);
					j++;
				}
			}
			ethmac[j] = 0;
		}
		fclose(fpConf);
		remove("../log/hwlog.txt");
	}
	else
	{
	 	printf("Log directory may be missing!\n");
	 	return 0;
	}
	
	// Memory
	// Modify by simon, 2023/11/25
	memset(meminfo, 0, 64);
	sprintf(meminfo, "%ld", totalMemory);
		/*
		sprintf(buf,"cat /proc/meminfo >../log/hwlog.txt");
		system(buf);
		fpConf = fopen("../log/hwlog.txt","r");
		if(fpConf != NULL)
		{
			fread(buf,2048,1,fpConf);
			offset = strstr(buf,"MemTotal:");
			if (offset != NULL)
			{
				for(i=0,j=0;i<64;i++)
				{
					if ((*(offset+i)=='\n') ||(*(offset+i)=='k'))
					{
						meminfo[j] = 0;
						break;
					}
					else if (isdigit(*(offset+i)))
					{
						meminfo[j] = *(offset+i);
						//printf("meminfo[%d] = %c\n", j, meminfo[j]);
						j++;
					}
				}
				meminfo[j] = 0;
			}
			fclose(fpConf);
			remove("../log/hwlog.txt");
		}
		else
		{
			printf("Log directory may be missing!\n");
			return 0;
		}
		*/

	// CPUInfo
	memset(cpuinfo, 0, 64);
	sprintf(buf,"cat /proc/cpuinfo >../log/hwlog.txt");
	system(buf);
	fpConf = fopen("../log/hwlog.txt","r");
	if(fpConf != NULL)
	{
		fread(buf,2048,1,fpConf);
		offset = strstr(buf,"cpu family");
		if (offset != NULL)
		{
			for(i=0,j=0;i<64;i++)
			{
				if (*(offset+i)=='\n')
				{
					cpuinfo[j] = 0;
					break;
				}
				else if (isdigit(*(offset+i)))
				{
					cpuinfo[j] = *(offset+i);
					//printf("cpuinfo[%d] = %c\n", j, cpuinfo[j]);
					j++;
				}
			}
		}
		offset = strstr(buf,"model");
		if (offset != NULL)
		{
			for(i=0;i<64;i++)
			{
				if (*(offset+i)=='\n')
				{
					cpuinfo[j] = 0;
					break;
				}
				else if (isdigit(*(offset+i)))
				{
					cpuinfo[j] = *(offset+i);
					//printf("cpuinfo[%d] = %c\n", j, cpuinfo[j]);
					j++;
				}
			}
		}
		offset = strstr(buf,"cache size");
		//offset = strstr(buf,"cpu MHz");
		//offset = strstr(buf,"bogomips");
		if (offset != NULL)
		{
			for(i=0;i<64;i++)
			{
				if (*(offset+i)=='\n')
				{
					cpuinfo[j] = 0;
					break;
				}
				else if (*(offset+i) == 'K')
				{
					//continue;
					break;
				}
				else if (isdigit(*(offset+i)))
				{
					cpuinfo[j] = *(offset+i);
					//printf("cpuinfo[%d] = %c\n", j, cpuinfo[j]);
					j++;
				}
			}
			cpuinfo[j] = 0;
		}
		fclose(fpConf);
		remove("../log/hwlog.txt");
	}
	else
	{
	 	printf("Log directory may be missing!\n");
	 	return 0;
	}
	
	strcpy(hwinfo, "");
	strcat(hwinfo, ethmac);
	i = j = strlen(ethmac);
	hwinfo[i++] = ethmac[0];
	hwinfo[i++] = ethmac[1];
	hwinfo[i++] = ethmac[2];
	hwinfo[i++] = ethmac[3];
	hwinfo[i] = 0;
	strcat(hwinfo, meminfo);
	j = strlen(meminfo);
	i += j;
	hwinfo[i++] = ethmac[4];
	hwinfo[i++] = ethmac[5];
	hwinfo[i++] = ethmac[6];
	hwinfo[i++] = ethmac[7];
	hwinfo[i] = 0;
	strcat(hwinfo, cpuinfo);
	j = strlen(cpuinfo);
	i += j;
	hwinfo[i++] = ethmac[8];
	hwinfo[i++] = ethmac[9];
	hwinfo[i++] = ethmac[10];
	hwinfo[i++] = ethmac[11];
	hwinfo[i] = 0;
	
	j = strlen(hwinfo);
	if (j == 0)
	{
		printf("Missing Activation Request Info!\n");
		return 0;
	}
	
	k = (j + 7) / 8;
	//printf("hwinfo: %s, len: %d, segment: %d\n", hwinfo, j, k);
	memset(hwinfo + j, '0', 128 - j);
	printf("xxx=%d\n",k);
	memset(act_req_code, 0, 128);
	for (i = 0; i < k; i++)
	{
		memset(TmpStr, 0, 64);
		DesCrypt(TmpStr, (BYTE*)(hwinfo + 8 * i), NULL, 0);
		memcpy(act_req_code + 8 * i, TmpStr, 8);
	}
	memset(ascii_buf, 0, 256);
	BcdToAscii(ascii_buf, act_req_code, k * 16);
	
	fpConf = fopen("../log/Activation_request_code.txt","w");
	if (fpConf != NULL)
	{
		fprintf(fpConf, "%s\n", ascii_buf);
		fclose(fpConf);
	}
	else
	{
		printf("Missing Activation_request_code file!\n");
		return 0;
	}
	
	memset(act_req_code_des, 0, 128);
	for (i = 0; i < k; i++)
	{
		memset(TmpStr, 0, 64);
		DesCrypt(TmpStr, act_req_code + 8 * i, NULL, 0);
		memcpy(act_req_code_des + 8 * i, TmpStr, 8);
	}
	//memset(ascii_buf, 0, 128);
	//BcdToAscii(ascii_buf, act_req_code_des, k * 16);
	//printf("Activation request code DES: %s\n", ascii_buf);
	
	if(memcmp(act_req_code_des,HDSerailNumber,k*8) != 0 && memcmp(act_req_code_des, &HDSerailNumber[4],k*8) != 0)
	{
		printf("Check HD license failed!\n");
		printf("Activation request code: %s\n", ascii_buf);
		printf("Please send ./log/Activation_request_code.txt to get the license\n");
		return 0;
	}
	printf("Check HD license... pass!\n");
	return 1;
}

static int CheckLicenseDate(const u_char license_date[3])
{
	time_t time_now = (unsigned long long)time(0);
	struct tm tm_now;
	localtime_r(&time_now, &tm_now);
	u_char cur_year = tm_now.tm_year + 1900 - 2000;
	u_char cur_mon = tm_now.tm_mon + 1;
	u_char cur_day = tm_now.tm_mday;

	if(cur_year > license_date[0])
	{
		printf("Check HD license date failed! license date year:mon:day=%d:%d%d\n",
									license_date[0] + 2000,
									license_date[1],
									license_date[2]);
		printf("Please send ./log/Activation_request_code.txt to get new license\n");
		return 0;
	}

	if(cur_year == license_date[0] &&
	   cur_mon > license_date[1])
   {
		printf("Check HD license date failed! license date year:mon:day=%d:%d%d\n",
									license_date[0] + 2000,
									license_date[1],
									license_date[2]);
		printf("Please send ./log/Activation_request_code.txt to get new license\n");
		return 0;
   }

	if(cur_year == license_date[0] && 
	   cur_mon == license_date[1] &&
       cur_day > license_date[2] )
	{
		printf("Check HD license date failed! license date year:mon:day=%d:%d%d\n",
									license_date[0] + 2000,
									license_date[1],
									license_date[2]);
		printf("Please send ./log/Activation_request_code.txt to get new license\n");
		return 0;
	}

	printf("Check HD license date... pass!\n");
	return 1;
}
/*************************************************
Function:        // setup_daemon
Description:     // make process running at daemon
Calls:           // 
Called By:       // main()
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void setup_daemon(void)
{
  //int i;
  pid_t pid;
  
  /*
	for (i=0; i<3; i++){
       close(i);
	}
	*/
	
	if ((pid = fork()) != 0)
		exit(0);
	setsid();
	//umask(0);

/*    switch (fork()){
		case -1:
			perror("setup_daemon(), 1st fork()");
			exit(2);
		case 0:
			if (setsid()==-1){ 
				perror("setup_daemon(), setsid()");
				exit(3);
			}
			switch (fork()){
				case -1:
					perror("setup_daemon(), 2nd fork()");
					exit(3);
				case 0:
					umask(0);
					return;
				default:
					exit(0);
			}
		default:
			exit(0);
	}*/
	return;
}

/*************************************************
Function:        // wxc2SetTermSignal
Description:     // make process accepting the signal from the  terminal 
Calls:           // 
Called By:       // main()
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // 
*************************************************/

static 
void wxc2SetTermSignal(struct termio *ptermio, void (*handler)(int))
{
  ioctl(0,TCGETA, ptermio);
  ptermio->c_cc[VINTR] = '\x03';
  ioctl(0,TCSETA, ptermio);

  signal(SIGINT, handler);
//  signal(SIGPIPE,handler);
  signal(SIGKILL,handler);
  signal(SIGSTOP,handler);
  signal(SIGTERM,handler);
}

/*************************************************
Function:        // wxc2Terminate
Description:     // Init parrallel port
Calls:           // 
Called By:       // main()
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // 
*************************************************/
static
void wxc2Terminate(int sig)
{
   //WriteParalPort(0,1);
   // b simon at 20240426
   //outb(0x00,0x37a);
   WriteParalPort(2,0);
   WriteParalPort(3,0);
   WriteParalPort(4,0);
   WriteParalPort(5,0);
   WriteParalPort(6,0);
   WriteParalPort(7,0);
   WriteParalPort(8,0);
   WriteParalPort(9,0);
   if(!sig){
	system("poweroff");
   }	
   exit(sig);
}

void writeDebug(const char *fmt, ...)
{
	char command[512];
	long l_time;
	struct tm *t;
	va_list ap;
	char message[1024];
	va_start(ap, fmt);
	vsprintf(message, fmt, ap);
	va_end(ap);
	
	l_time = time(NULL);
	t = localtime(&l_time);
	
	sprintf(command,"echo '%02d:%02d:%02d %s' >>../log/omcmain_%d_%d.log",t->tm_hour, t->tm_min, t->tm_sec, message, t->tm_mon + 1, t->tm_mday);
	system(command);
}
