/*************************************************
File name:	paraComm.c
Author: 	Cui Ticun
Version:	9.00.00 
Date:  		2007-7-1
Description:Operate system's parameter
						
History:               
No. 
Author  
Date    
Version   
Description
*************************************************/
#include "paraComm.h"

/******************************************************/
/******            Heartbeat Parameter           ******/
/******************************************************/
DWORD PROC_HEARTBEAT_OID[12]={1,3,6,1,4,1,1373,2,4,10,1};
int PROC_HEARTBEAT_OIDLEN=11;
int sendHeartbeat();

/*******define in omcLib/omcDbLib.c ***/
MYSQL 		*mysql_conn();
MYSQL_RES	*mysql_getres();
int 		mysql_getnores();

/******Private Functions***/
int		paraCommScan();
int		paraCommProc();
int		respProc(int *commNo, snmp_pdu * pdu);
int		updateCommTable(int commNo);
int		getSysAddr(int commNo);
int		getParamTable(int sysTypeNo, int sysNo, int paramType,
				  char *tableName);
int		mkVarArr(int commNo, var_list * varArr);
int 	mkAddr(int commNo, snmp_addr * msgAddr);
int		mkPdu(int commNo, var_list * varArr, snmp_pdu * pdu);
int		initUnitComm(int commNo);
void	freeParamSet(int commNo);
void optErr(unitComm *ucomm);


/*******Global Var*********/
FILE *paraCommLog;
int		oldDay = 0;					//1-31

static unitComm commArr[MaxCommNum];
static MYSQL *dbConn;

static int MaxErrorStatusNum = 19;
static char errorStatusDescArr[19][30] =
	{ "NoError", "TooBig", "NoSuchName", "BadValue", "ReadOnly",
	"GenErr", "NoAccess", "WrongType", "WrongLength", "WrongEncoding",
	"wrongValue", "noCreation", "inconsistentValue", "resourceUnavailabe",
		"commitFailed",
	"UndoFailed", "AuthorizationError", "NoWritable", "inconsistentName"
};

int paraComm_timerCount = 0;	//for paraCommTimer

int checkMibSystem(int sysTypeNo)
{
	switch(sysTypeNo)
	{
	case 320://MSC
	case 355://SMEG
	case 375://OPPS
	case 225://XAPP
	case 260://SMPP
	case 311://AAS
	case 325://VLR
	case 330://HLR
	case 340://AUC
	case 350://SMSC
	case 380://EIR
	case 385://MRFC
	case 360://PPS
	case 361://MME
	case 362://SPGW
	case 363://IMS
	case 364://ACS
	case 365://UDM
	case 366://AUSF
	case 390://VMS
	case 378://iPALIM
	case 379://iRLS
	case 386://MHC
	case 370://MNP
	case 387://iGRS
	case 389://IUUPGW	
	case 391://TMG
	case 392://AMRMG
	case 393://GbC
	case 394://GbC
	case 395://RCM
	case 222://MTP3
	case 223://SCCP
	case 480://DEA
		return 1;
		break;
	default: 
		return 0;
		break;
	}
	
	return 0;
}

int checkPlatHasSubSysNo(int sysTypeNo,int sysNo)
{
	// modified by simon at 2024/04/12
	//if(sysNo != 9)
	if (sysNo != 9 && sysNo != 3 && sysNo != 5 && sysNo != 6 ) // 9-MSS,3-HLR,5-OCS/PPS,6-SMSC
	{
		switch(sysTypeNo)
		{
		case 260://SMPP
		case 222://MTP3
		case 223://SCCP
			return 1;
			break;
		default:
			return 0;
			break;
		}
	}

	return 0;	
}

/*************************************************
Function:        // paraCommInit
Description:     // 1.Init OMC_PUB.parameterComm
				 // 2.Init Commands Array
				 // 3.Init Every module's paramConf
Calls:           // omcLogInit();initUnitComm();initDbFromMib();
Called By:       // 
Table Accessed:  // 
Table Updated:   // OMC_PUB.parameterComm;OBJ_xxx.paramConf
Input:           // 
Output:          // 
Return:          // 1:OK,0:error
Others:          // 
*************************************************/
//extern int global_mod_index;
int paraCommInit()
{
	int commNo;
	long nowTime;
	struct tm *nowTm;
	char commQuery[128] = "\0";
		
	//init log
	omcLogInit(paraComm_LogPath, paraComm_LogFile, &paraCommLog);
	nowTime = time(NULL);
	nowTm = localtime(&nowTime);
	oldDay = nowTm->tm_mday;

	//init db connect
	dbConn = mysql_conn(HOSTNAME, PUB_DB);
	if (dbConn == NULL) {
		omcLog(paraCommLog,"[ERR][paraCommInit]:mysql connect OMC_PUB");	
		return (0);
	}
	
	//init command table
	sprintf(commQuery, "DELETE FROM %s", CommTable);
	mysql_getnores(dbConn, commQuery);

	//init command arrary
	for (commNo = 0; commNo < MaxCommNum; commNo++) {
		initUnitComm(commNo);
	}
	
	//init every module's paramCOnf
	//for(global_mod_index=0;global_mod_index<global_mod_total;global_mod_index++)
	//{
		initDbFromMib();
	//}
	return (1);
}

/*************************************************
Function:        // sendHeartbeat
Description:     // Send process heartbeat to beatProc
Calls:           // snmp_send
Called By:       // on_Timer
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 1:OK; 0:Fail
Others:          // 
*************************************************/
int sendHeartbeat()
{
	snmp_pdu pdu;
	snmp_addr addr;
	char proc_name[16];
	
	memset(proc_name,0,16);
	sprintf(proc_name,"paraComm");
	
	//pdu
	memset(&pdu,0,sizeof(snmp_pdu));
	pdu.pdu_type=7;
	pdu.request_id=0;
	sprintf(pdu.community,"public");
	pdu.var_num=1;
	pdu.error_status=0;
	pdu.error_index=0;
	
	//Addr
	addr.local_port = 4957;
	//addr.remote_ip = inet_addr("127.0.0.1");
	addr.remote_ip = GetLocalIP();
	addr.broadcast = 0;
	addr.remote_port = 4957;
	
	//Varlist
	memcpy(pdu.var[0].oid,PROC_HEARTBEAT_OID,PROC_HEARTBEAT_OIDLEN*sizeof(DWORD));

	pdu.var[0].oidlen=PROC_HEARTBEAT_OIDLEN;
	pdu.var[0].vartype=0x04;
	pdu.var[0].msglen=16;
	memcpy(pdu.var[0].msg,proc_name,16);
	
	if(snmp_send(&pdu, &addr) <= 0)
	{
		omcLog(paraCommLog,"Send heartbeat fail");
		return 0;
	}
	return 1;
}

/*************************************************
Function:        // paraCommTimer
Description:     // 设备参数定时处理主函数。
				 // 扫描命令表，插入命令到命令数组。
				 // 处理命令数组中的命令。

Calls:           // paraCommScan();paraCommProc();omcLogInit();
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 1:OK,0:error
Others:          // 
*************************************************/
unsigned long heartbeat_timeout=0;
int paraCommTimer()
{
	int returnResult=0;
	
	
	if(time(NULL) - heartbeat_timeout > 5)
	{
		heartbeat_timeout=time(NULL);
		sendHeartbeat();
	}
	
	paraCommScan();
	
	if (paraComm_timerCount > 5000) {//100s	
		long l_time;
		struct tm *t;
		l_time = time(NULL);
		t = localtime(&l_time);
		if (t->tm_mday != oldDay) {
			//init logfile,create a new log file to restore log
			omcLogInit(paraComm_LogPath, paraComm_LogFile, &paraCommLog);
			oldDay = t->tm_mday;
		}
		paraComm_timerCount = 0;
	}
	paraComm_timerCount++;
	

	returnResult=paraCommProc();
	if (returnResult) {
		return (1);
	} else {
		return (0);
	}
}


/*************************************************
Function:        // paraCommScan
Description:     // 扫描命令表，插入命令到命令数组。
				 // 最多可同时处理32条命令

Calls:           // 
Called By:       // int paraCommTimer()
Table Accessed:  // OMC_PUB.parameterComm
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 1->find command,0->no command,-1->failed
Others:          // 
*************************************************/
int paraCommScan()
{
	int i = 0, commNo = 0;
	
	char commQuery[512] 	= "\0";
	char cfgQuery[512] 		= "\0";
	char paramConfQuery[512]= "\0";
	char paramQuery[1024] 	= "\0";
	char paramTableName[64] = "\0";
	MYSQL_RES *commResult = NULL,*cfgResult = NULL,*paramConfResult = NULL,*paramResult = NULL;;
	MYSQL_ROW commRow,cfgRow, paramConfRow;

/*
	char paramSelect[512]	=	"SELECT T1.level_1,T1.level_2,T1.level_3,T1.level_4,T1.level_5,"
								"T1.level_6,T1.level_7,T1.level_8,T1.level_9,T1.level_10,"
								"T1.instanceNo,T1.initValue,T1.readValue,T2.valueType";
*/
//AdministrationState do not set

	char paramSelect[512]	=	"SELECT T1.level_1,T1.level_2,T1.level_3,T1.level_4,T1.level_5,"
								"T1.level_6,T1.level_7,T1.level_8,T1.level_9,T1.level_10,"
								"T1.instanceNo,T1.`initValue`,T1.`readValue`,T2.valueType,T2.name_2";
	

	char queryOrderBy[256] 	=	" T1.level_1,T1.level_2,T1.level_3,T1.level_4,T1.level_5,"\
						  		"T1.level_6,T1.level_7,T1.level_8,T1.level_9,T1.level_10";
	char levelStr[64]		= "\0";
	char queryWhere[512]	= "\0";
	
	char *oneOid;
	char *oneInstanceNo;
	char instanceNo[32];

	sprintf(commQuery,
			"SELECT commId,commType,sysTypeNo,sysNo,subSysNo,paramType,objId,instanceNo"
			" FROM %s WHERE commState = '%d' ORDER BY sendTime",
			CommTable, nWaitProc);
	//printf("commQuery=%s\n",commQuery);
	commResult = (MYSQL_RES *) mysql_getres(dbConn, commQuery);
	if (commResult == NULL) {
		omcLog(paraCommLog, " Database may be stopped,when get commands");
		return (-1);
	} else if (mysql_num_rows(commResult) == 0) {
		mysql_free_result(commResult);
		return (0);
	}
	
	while ((commRow = mysql_fetch_row(commResult))) {
		//Try to Find a  available command array
		for (commNo = 0; commNo < MaxCommNum; commNo++) {
			if ((commArr[commNo].procState == nIdle)
				&& (commArr[commNo].commState != nWaitProc)
				&& (commArr[commNo].commState != nInProc)) {
				initUnitComm(commNo);
				break;
			} 
		}//end of for(..)
		
		if (commNo == MaxCommNum) {
			omcLog(paraCommLog, "Commands array is full");
			break;
		}
		
		commArr[commNo].commState	= nInProc;
		commArr[commNo].commId		= atoi(commRow[0]);
		commArr[commNo].commType	= atoi(commRow[1]);
		commArr[commNo].sysTypeNo	= atoi(commRow[2]);
		commArr[commNo].sysNo		= atoi(commRow[3]);
		commArr[commNo].subSysNo	= atoi(commRow[4]);
		commArr[commNo].paramType	= (BYTE) atoi(commRow[5]);

		//Get Active IP From IpTable
		if (!getSysAddr(commNo)) {
			sprintf(commArr[commNo].desc, CONF_COMMAND_ERR_0101);
			commArr[commNo].commState = nProcFail;
			commArr[commNo].procState = nIdle;
			updateCommTable(commNo);
			initUnitComm(commNo);
			continue;
		}
		
		//Get General Info From ConfTable
		sprintf(cfgQuery,
				"SELECT maxMsgLen,snmpHead,snmpPort,needMuliObj,snmpCommunity "
				"FROM %s WHERE sysTypeNo='%d'", ConfTable,
				commArr[commNo].sysTypeNo);
		//printf("cfgQuery=%s\n",cfgQuery);
		cfgResult = (MYSQL_RES *) mysql_getres(dbConn, cfgQuery);
		if (cfgResult == NULL) {
			omcLog(paraCommLog, "Get system configuration informations error!!");
			return (-1);
		}
		if ((cfgRow = mysql_fetch_row(cfgResult)) != NULL) {
			commArr[commNo].snmpInfo.maxMsgLen	= atoi(cfgRow[0]);	//<--
			commArr[commNo].snmpInfo.dstPort 	= atoi(cfgRow[2]);	//<--
			commArr[commNo].snmpInfo.needMuliObj= atoi(cfgRow[3]);	//<--
			sprintf(commArr[commNo].snmpInfo.snmpCommunity, "%s", cfgRow[4]);	//<--
			
			i = 0;			
			while ((oneOid = strsep(&(cfgRow[1]), "."))) {
				commArr[commNo].snmpInfo.oid[i] = atoi(oneOid);	//<--
				i++;
			}
			commArr[commNo].snmpInfo.preOidLen = i;	//<--
			commArr[commNo].snmpInfo.oidLen = i;	//<--
			if (i < 1) {
				omcLog(paraCommLog, "Get objId error!!");
				mysql_free_result(cfgResult);
				return (-1);
			}
		}
		mysql_free_result(cfgResult);

		//Get Oid Info		
		i = 0;
		queryWhere[0]=0;
		while ((oneOid = strsep(&(commRow[6]), ".")) != NULL) {
			commArr[commNo].snmpInfo.oid[i+commArr[commNo].snmpInfo.oidLen] = atoi(oneOid);
			i++;
			levelStr[0] = 0;
			if(i==1){
				sprintf(levelStr, "T1.level_%d = '%s' ", i, oneOid);
			}else{
				sprintf(levelStr, "AND T1.level_%d = '%s' ", i, oneOid);
			}
			strcat(queryWhere, levelStr);
		}	
		commArr[commNo].snmpInfo.oidLen = commArr[commNo].snmpInfo.oidLen+i;
		if (commArr[commNo].snmpInfo.oidLen < 1) {
			omcLog(paraCommLog, "Get subObjId error!!");
			return (-1);
		}
			
		sprintf(paramConfQuery,
				"SELECT T1.level_%d FROM OBJ_%d.paramConf AS T1 WHERE %s AND level_%d !=0 ORDER BY %s",
				i+1,commArr[commNo].sysTypeNo,queryWhere, i+1,queryOrderBy);
		//printf("paramConfQuery=%s\n",paramConfQuery);
		paramConfResult = (MYSQL_RES *) mysql_getres(dbConn, paramConfQuery);
		if (paramConfResult == NULL) {
			omcLog(paraCommLog,
				   " Database may be stopped,when get paramConf");
			return (-1);
		}
		
		commArr[commNo].snmpInfo.columnNum=mysql_num_rows(paramConfResult); 		
		i=0;
		while ((paramConfRow = mysql_fetch_row(paramConfResult))) {
			commArr[commNo].snmpInfo.column[i]=atoi(paramConfRow[0]);
			i++;			
		}
		
		mysql_free_result(paramConfResult);
		
		//Get InstanceNo info
		if(strlen(commRow[7])>0){
			//ISSUE-2
			if(strstr(commRow[7],"."))
				sprintf(levelStr, "AND T1.instanceNo = '%s' ",commRow[7]);
			else
				sprintf(levelStr, "AND T1.instanceNo = '%s' ",commRow[7]);
			strcat(queryWhere, levelStr);
			
			strcpy(instanceNo,commRow[7]);
			i = 0;
			while ((oneInstanceNo = strsep(&(commRow[7]), ".")) != NULL) {
				commArr[commNo].snmpInfo.instanceNo[i] = atoi(oneInstanceNo);
				i++;
			}
  			
			commArr[commNo].snmpInfo.instanceNoLevel = i;
			if (commArr[commNo].snmpInfo.instanceNoLevel < 1) {
				omcLog(paraCommLog, "Get instanceNo error!!");
				return (-1);
			}
		}
		
		getParamTable(commArr[commNo].sysTypeNo, commArr[commNo].sysNo,
					  commArr[commNo].paramType, paramTableName);
		sprintf(commArr[commNo].paramTable, "%s", paramTableName);	//<--
			
		for(i=1;i<=10;i++){
			sprintf(levelStr, "AND T1.level_%d = T2.level_%d ", i,i);
			strcat(queryWhere, levelStr);
		}
		
		
		if(checkMibSystem(commArr[commNo].sysTypeNo))
		{
			/*
			if(commArr[commNo].commType==nSetComm){
				sprintf(paramQuery,"%s FROM %s AS T1,OBJ_%d.paramConf AS T2 "
								   " WHERE %s AND (T2.maxAccess='%d' OR T2.maxAccess='%d') ORDER BY %s,instanceNo ",
								   paramSelect,paramTableName,commArr[commNo].sysTypeNo,
								   queryWhere,MIB_ACCESS_READWRITE,MIB_ACCESS_CREATE,queryOrderBy);	   	
			*/
			if(commArr[commNo].commType==nSetComm){
				sprintf(paramQuery,"%s FROM %s AS T1,OBJ_%d.paramConf AS T2 "
								   " WHERE %s AND T2.maxAccess='%d' ORDER BY %s,instanceNo ",
								   paramSelect,paramTableName,commArr[commNo].sysTypeNo,
								   queryWhere,MIB_ACCESS_READWRITE,queryOrderBy);	   	
								   
				//ISSUE-3
				if(checkPlatHasSubSysNo(commArr[commNo].sysTypeNo,commArr[commNo].sysNo))
				{
					sprintf(paramQuery,"%s FROM %s AS T1,OBJ_%d.paramConf AS T2 "
								   " WHERE %s AND T2.maxAccess='%d' AND T1.subSysNo='%d' ORDER BY %s,instanceNo ",
								   paramSelect,paramTableName,commArr[commNo].sysTypeNo,
								   queryWhere,MIB_ACCESS_READWRITE,commArr[commNo].subSysNo,queryOrderBy);	
				}				   
			}else if(commArr[commNo].commType!=nGetBulkComm){
				sprintf(paramQuery,"%s FROM %s AS T1,OBJ_%d.paramConf AS T2 "
								   " WHERE %s AND T2.maxAccess!='%d' AND T2.maxAccess!='%d' ORDER BY %s,instanceNo ",
								   paramSelect,paramTableName,commArr[commNo].sysTypeNo,
								   queryWhere,MIB_ACCESS_NOACCESS,MIB_ACCESS_NOTIFY,queryOrderBy);
				
				//ISSUE-3
				if(checkPlatHasSubSysNo(commArr[commNo].sysTypeNo,commArr[commNo].sysNo))
				{
					sprintf(paramQuery,"%s FROM %s AS T1,OBJ_%d.paramConf AS T2 "
								   " WHERE %s AND T2.maxAccess!='%d' AND T2.maxAccess!='%d' AND T1.subSysNo='%d' ORDER BY %s,instanceNo ",
								   paramSelect,paramTableName,commArr[commNo].sysTypeNo,
								   queryWhere,MIB_ACCESS_NOACCESS,MIB_ACCESS_NOTIFY,commArr[commNo].subSysNo,queryOrderBy);
				}
			}
			 omcLog(paraCommLog,"\nSQL=%s",paramQuery);

		}else{
			strcat(paramSelect,",T2.length");
			if(commArr[commNo].paramType!=nSubSysParam){
				if(commArr[commNo].commType==nSetComm){
					sprintf(paramQuery,"%s FROM %s AS T1,OBJ_%d.paramConf AS T2 "
									   " WHERE %s AND subSysNo='%d' AND (T2.operType='2' OR T2.operType='3' OR T2.operType='4') ORDER BY %s,instanceNo ",
									   paramSelect,paramTableName,commArr[commNo].sysTypeNo,queryWhere,nPubFlag,queryOrderBy);
				}else{
					sprintf(paramQuery,"%s FROM %s AS T1,OBJ_%d.paramConf AS T2 "
									   "WHERE %s AND subSysNo='%d' AND (T2.operType='1' OR T2.operType='3' OR T2.operType='4') ORDER BY %s,instanceNo ",
									   paramSelect,paramTableName,commArr[commNo].sysTypeNo,queryWhere,nPubFlag,queryOrderBy);
				}	
			}else{
				if(commArr[commNo].commType==nSetComm){
					sprintf(paramQuery,"%s FROM %s AS T1,OBJ_%d.paramConf AS T2 "
									   " WHERE %s AND subSysNo='%d' AND (T2.operType='2' OR T2.operType='3' OR T2.operType='4') ORDER BY %s,instanceNo ",
									   paramSelect,paramTableName,commArr[commNo].sysTypeNo,queryWhere,commArr[commNo].subSysNo,queryOrderBy);
				}else{
					sprintf(paramQuery,"%s FROM %s AS T1,OBJ_%d.paramConf AS T2 "
									   " WHERE %s AND subSysNo='%d' AND (T2.operType='1' OR T2.operType='3' OR T2.operType='4') ORDER BY %s,instanceNo ",
									   paramSelect,paramTableName,commArr[commNo].sysTypeNo,queryWhere,commArr[commNo].subSysNo,queryOrderBy);
				}
			}				
		}
		
		if(strlen(paramQuery)>0){   		
			//printf("paramQuery=%s\n",paramQuery);
			paramResult = (MYSQL_RES *) mysql_getres(dbConn, paramQuery);
			if (paramResult == NULL) {
				omcLog(paraCommLog,
					   " Database may be stopped,when get paramSet");
				return (-1);
			}
			commArr[commNo].totalNum = mysql_num_rows(paramResult);	//<--
			if (commArr[commNo].totalNum <= 0) {
				omcLog(paraCommLog,
					   "TotalNum <= 0,Cannot get the object value record!\nSQL=%s",
					   paramQuery);
				sprintf(commArr[commNo].desc,CONF_COMMAND_ERR_0201);
        	
				commArr[commNo].commState = nProcFail;
				commArr[commNo].procState = nIdle;
				mysql_free_result(paramResult);
				commArr[commNo].paramSet = NULL;
				updateCommTable(commNo);
				initUnitComm(commNo);
				return (-1);
			} else {
				commArr[commNo].finishNum = 0;	//<--
				commArr[commNo].paramSet = paramResult;	//<--    
        	
				updateCommTable(commNo);
			}
		}
		
		
#if paraComm_DEBUG
		//General Info
		omcLog(paraCommLog,"commArr[%d].commId   =%d", commNo,
			   commArr[commNo].commId);
		omcLog(paraCommLog,"commArr[%d].commType=%d", commNo,
			   commArr[commNo].commType);
		omcLog(paraCommLog,"commArr[%d].sysTypeNo=%d", commNo,
			   commArr[commNo].sysTypeNo);
		omcLog(paraCommLog,"commArr[%d].sysNo    =%d", commNo,
			   commArr[commNo].sysNo);
		omcLog(paraCommLog,"commArr[%d].subSysNo =%d", commNo,
			   commArr[commNo].subSysNo);
		omcLog(paraCommLog,"commArr[%d].paramType =%d", commNo,
			   commArr[commNo].paramType);
		
		omcLog(paraCommLog,"commArr[%d].snmpInfo.dstIP   =%s", commNo,
			   commArr[commNo].snmpInfo.dstIP);
		omcLog(paraCommLog,"commArr[%d].snmpInfo.needMuliObj=%d", commNo,
			   commArr[commNo].snmpInfo.needMuliObj);
		omcLog(paraCommLog,"commArr[%d].snmpInfo.dstPort=%ld", commNo,
			   commArr[commNo].snmpInfo.dstPort);
		omcLog(paraCommLog,"commArr[%d].snmpInfo.maxMsgLen    =%ld", commNo,
			   commArr[commNo].snmpInfo.maxMsgLen);
		omcLog(paraCommLog,"commArr[%d].snmpInfo.snmpCommunity =%s", commNo,
			   commArr[commNo].snmpInfo.snmpCommunity);
			   
		omcLog(paraCommLog,"commArr[%d].snmpInfo.preOidLen   =%d", commNo,
			   commArr[commNo].snmpInfo.preOidLen);
		omcLog(paraCommLog,"commArr[%d].snmpInfo.oidLen=%d", commNo,
			   commArr[commNo].snmpInfo.oidLen);
		for(i=0;i<commArr[commNo].snmpInfo.oidLen;i++){
			omcLog(paraCommLog,"commArr[%d].snmpInfo.oid=%d", commNo,
			   commArr[commNo].snmpInfo.oid[i]);		
		}
		omcLog(paraCommLog,"commArr[%d].snmpInfo.columnNum=%d", commNo,
			   commArr[commNo].snmpInfo.columnNum);
		for(i=0;i<commArr[commNo].snmpInfo.columnNum;i++){
			omcLog(paraCommLog,"commArr[%d].snmpInfo.column=%d", commNo,
			   commArr[commNo].snmpInfo.column[i]);		
		}	
		omcLog(paraCommLog,"commArr[%d].snmpInfo.instanceNoLevel=%d", commNo,
			   commArr[commNo].snmpInfo.instanceNoLevel);
		for(i=0;i<commArr[commNo].snmpInfo.instanceNoLevel;i++){
			omcLog(paraCommLog,"commArr[%d].snmpInfo.instanceNo=%d", commNo,
			   commArr[commNo].snmpInfo.instanceNo[i]);		
		}
		
		omcLog(paraCommLog,"commArr[%d].paramTable=%s", commNo,
			   commArr[commNo].paramTable);
		
	  
		omcLog(paraCommLog,"commArr[%d].procState=%d", commNo,
			   commArr[commNo].procState);
		omcLog(paraCommLog,"commArr[%d].commState=%d", commNo,
			   commArr[commNo].commState);
#endif
		updateCommTable(commNo);	
	}							//end of while(..)
	mysql_free_result(commResult);
	return (1);
}


/*************************************************
Function:        // paraCommProc
Description:     // 设备参数命令处理函数，这个函数是该模块的核心函数
				 // 1.根据各个命令的状态处理每个命令
				 // 2.判断命令的超时
				 // 3.处理回应消息
				 // 4.合成，发送消息

Calls:           // 
Called By:       // paraCommTimer
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 2->finish all,1->finish part,0->failed
Others:          // 
*************************************************/

int paraCommProc()
{
	int i = 0;
	int j = 0;
	int errorIndex;
	char errorCause[128];	
	char tmpStr[32];
	int idleCommCount = 0;
	snmp_pdu tmpPdu;
	snmp_addr tmpAddr;
	var_list tmpVarArr[MaxVarNum];
	
#if paraComm_DEBUG
	clrscr();
	printf
		("\n commId  systemId  systemIp comm/procState finish/total Desc");
#endif
	
	for (i = 0; i < MaxCommNum; i++) {
#if paraComm_DEBUG
		printf("\n %d \t %d-%d-%d  %s \t %d/%d \t %d/%d  \t%s ", i,
			   commArr[i].sysTypeNo, commArr[i].sysNo, commArr[i].subSysNo,
			   commArr[i].snmpInfo.dstIP,
			   commArr[i].commState, commArr[i].procState,
			   commArr[i].finishNum, commArr[i].totalNum, commArr[i].desc);
#endif
		if (commArr[i].commState == nInProc) {
#if paraComm_DEBUG
			omcLog(paraCommLog, " commArr[%d]:", i);
			omcLog(paraCommLog, " commState = %d \t procState = %d",
				   commArr[i].commState, commArr[i].procState);
#endif
			switch (commArr[i].procState) {
			case nIdle:
				if(commArr[i].commType!=nGetBulkComm&&commArr[i].totalNum==commArr[i].finishNum){
					commArr[i].commState = nOutProc;
					commArr[i].procState = nIdle;
					sprintf(commArr[i].desc, CONF_COMMAND_ERR_0000);
					updateCommTable(i);
					initUnitComm(i);
					freeParamSet(i);
					break;
				}
				
				
				mkVarArr(i, tmpVarArr);	
				
				mkAddr(i, &tmpAddr);
				mkPdu(i, tmpVarArr, &tmpPdu);
				
				commArr[i].waitTimeCount = 0;
				commArr[i].timeoutCount = 0;
				if (snmp_send(&tmpPdu, &tmpAddr) > 0) {
#if paraComm_DEBUG
{
		int k,kk;
		
					omcLog(paraCommLog, " send snmp message ok!");
					
					for(k=0;k<tmpPdu.var_num;k++)
					{
						for(kk=0;kk<tmpPdu.var[k].oidlen;kk++)
						{
							printf("%ld ",tmpPdu.var[k].oid[kk]);
						}
						printf("\n");
					}
}
#endif
					commArr[i].procState = nWaitResponse;
				} else {
					omcLog(paraCommLog, "Send snmp message failed!(IP=%s)",
						   commArr[i].snmpInfo.dstIP);
					commArr[i].commState = nProcFail;
					sprintf(commArr[i].desc,CONF_COMMAND_ERR_0301);
					updateCommTable(i);
					commArr[i].procState = nIdle;
					initUnitComm(i);
				}
				break;
			case nWaitResponse:
				mkAddr(i, &tmpAddr);
				if (snmp_receive(&tmpPdu, &tmpAddr) > 0) {//received msg
					int respProcReturn = 0;
#if paraComm_DEBUG
					omcLog(paraCommLog, " Receive  snmp message ok!");
#endif
					respProcReturn = respProc(&i, &tmpPdu);	//here changed commState's value
					if (respProcReturn > 0) {//vaild message
						commArr[i].waitTimeCount = 0;
						commArr[i].timeoutCount = 0;
					} else if (respProcReturn == 0) {//invaild message
						commArr[i].waitTimeCount++;
						omcLog(paraCommLog,
							   "Invailed response message,throw away");
						sprintf(commArr[i].desc,CONF_COMMAND_ERR_0401);
						//Don't send msg again when find invaild message,
						//Because iptrans is a FIFO buffer
						if (commArr[i].waitTimeCount % 3) {
							continue;
						}
					} else {//error report message
						commArr[i].commState = nProcFail;
						
						/***********************/
						errorIndex=tmpPdu.error_index-1;
						//errorIndex=tmpPdu.error_index;
						//printf("error_status=%d,error_index=%d,len=%d\n",tmpPdu.error_status,errorIndex,tmpPdu.var[errorIndex].msglen);
						//printf("pdu_type=%d,var_type=%d\n",tmpPdu.pdu_type,tmpPdu.var[errorIndex].vartype);
						for(j=0;j<tmpPdu.var[errorIndex].msglen;j++)
						{
							errorCause[j]=toascii(tmpPdu.var[errorIndex].msg[j]);
						}
						errorCause[j]=0;
						//printf("msg=%s\n",errorCause);/20071103
						if(tmpPdu.error_status <= 9)
							sprintf(tmpStr,"0%d",tmpPdu.error_status);
						else	
							sprintf(tmpStr,"%d",tmpPdu.error_status);
						sprintf(commArr[i].desc,"05%s:%s",tmpStr,errorCause);
						optErr(&commArr[i]);
						//printf("desc:%s\n",commArr[i].desc);
						/************************/
						updateCommTable(i);
						initUnitComm(i);
					}
					
					switch (commArr[i].commState) {
					case nInProc:
						if(commArr[i].commType!=nGetBulkComm){
							if(commArr[i].totalNum==commArr[i].finishNum){
								commArr[i].commState = nOutProc;
								commArr[i].procState = nIdle;
								sprintf(commArr[i].desc, CONF_COMMAND_ERR_0000);
								updateCommTable(i);
								initUnitComm(i);
								freeParamSet(i);
								break;
							}
							mkAddr(i, &tmpAddr);
							
							mkVarArr(i, tmpVarArr);
							mkPdu(i, tmpVarArr, &tmpPdu);
							commArr[i].waitTimeCount = 0;
							commArr[i].timeoutCount = 0;
							if (snmp_send(&tmpPdu, &tmpAddr) > 0) {
								commArr[i].procState = nWaitResponse;
								updateCommTable(i);
							} else {
								commArr[i].commState = nProcFail;
								commArr[i].procState = nIdle;
								sprintf(commArr[i].desc,CONF_COMMAND_ERR_0301);
								omcLog(paraCommLog,
									   "Send snmp message failed!");
								updateCommTable(i);
								initUnitComm(i);
							}    
						}
						break;
					case nOutProc:
						commArr[i].procState = nIdle;
						sprintf(commArr[i].desc, CONF_COMMAND_ERR_0000);
						updateCommTable(i);
						initUnitComm(i);
						break;
					default:	//error
						commArr[i].commState = nProcFail;
						commArr[i].procState = nIdle;
						sprintf(commArr[i].desc, CONF_COMMAND_ERR_0402);
					//printf("desc:%s\n",commArr[i].desc);	
					
						updateCommTable(i);
						initUnitComm(i);
						break;
					}
					
				} else {		//not received msg
#if paraComm_DEBUG
					omcLog(paraCommLog, " Receive  snmp message failed!");
#endif
					commArr[i].waitTimeCount++;
#if paraComm_DEBUG
					if(commArr[i].waitTimeCount>16)
						omcLog(paraCommLog,
							   "commId=%ld \t waitTimeCount=%d \t timeoutCount=%d",
							 commArr[i].commId,
							 commArr[i].waitTimeCount,
							 commArr[i].timeoutCount);
#endif
					if (commArr[i].waitTimeCount >= 16) {//Time out
						commArr[i].waitTimeCount = 0;
						commArr[i].timeoutCount++;
						if (commArr[i].timeoutCount > 4) {
							commArr[i].timeoutCount=0;
							commArr[i].commState = nProcFail;
							sprintf(commArr[i].desc, CONF_COMMAND_ERR_0403);
							omcLog(paraCommLog, "Response timeout");
							updateCommTable(i);
							initUnitComm(i);
							commArr[i].procState = nIdle;
						} else {//resend msg
							if(commArr[i].totalNum==commArr[i].finishNum&&commArr[i].commType!=nGetBulkComm){
								commArr[i].commState = nOutProc;
								commArr[i].procState = nIdle;
								sprintf(commArr[i].desc, CONF_COMMAND_ERR_0000);
								updateCommTable(i);
								initUnitComm(i);
								break;
							}
							//ISSUE-1
							if(commArr[i].sysTypeNo==223)
							{
								commArr[i].timeoutCount++;
								break;
							}
							
							mkAddr(i, &tmpAddr);
							mkVarArr(i, tmpVarArr);

							mkPdu(i, tmpVarArr, &tmpPdu);
							if (snmp_send(&tmpPdu, &tmpAddr) > 0) {
								commArr[i].procState = nWaitResponse;
							} else {
								commArr[i].commState = nProcFail;
								sprintf(commArr[i].desc,CONF_COMMAND_ERR_0301);
								omcLog(paraCommLog,
									   "failed to send snmp message!");
								updateCommTable(i);
								//commArr[i].procState = nIdle;
							}
						}
					}			//end of time out handle
				}				//end of not received msg
				break;
			default:
				commArr[i].procState = nIdle;
				commArr[i].commState = nProcFail;
				sprintf(commArr[i].desc,CONF_COMMAND_ERR_9999);
				omcLog(paraCommLog, "unknown procState,Please check!");
				break;
			}					//end of switch(..)
		} else {
			idleCommCount++;
		}
	}							//end of for(..)
	
	if (idleCommCount == MaxCommNum) {
		snmp_receive(&tmpPdu, &tmpAddr);
		return (2);
	} else {
		return (1);
	}
}


/*************************************************
Function:        // respProc
Description:     // 处理命令编号为commNo的命令的回应消息。
				 // commNo为命令编号，由于需要比较回应消息与各个命令的request_id是否相等，并可能根据回应消息改变commNo

Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 1  -> ok;0  -> invalid msg;-1 -> error report msg
Others:          // 
*************************************************/
int respProc(int *oldCommNo, snmp_pdu * pdu)
{	
	int i, j, commNo;
	char updateField[16] = "readValue";
	char updateSql[8192];
	char tmpStr[4096];
	int str_index;

	
	snmp_pdu tmpPdu;
	snmp_addr tmpAddr;
	
	//Check commNo
	if (*oldCommNo >= MaxCommNum) {
		omcLog(paraCommLog, " Error: oldCommNo is too big (%d)",
			   *oldCommNo);
		return (0);
	}
	commNo = *oldCommNo;

	//Check PDU Type
	if (pdu->pdu_type != PDU_RSP) {
		omcLog(paraCommLog, " Error pdu type:%d(!=Resp%d)", pdu->pdu_type,
			   PDU_RSP);
		return (0);
	}

	//Check Request ID
	if (pdu->request_id != commArr[commNo].commId) {
		int isRequestIdMatch = 0;
		for (i = 0; i < MaxCommNum; i++) {
			if (pdu->request_id == commArr[i].commId) {
				isRequestIdMatch = 1;
				*oldCommNo = i;
				commNo = i;
				break;
			}
		}
		if (isRequestIdMatch == 0) {
			omcLog(paraCommLog, "Unknown pdu->request_id(%ld) ",
				   pdu->request_id);
			return (0);
		}
	}

	for (i = 0; i < pdu->var_num; i++) {
		int		tmpLongInt = 0;
		char	tmpValue[512] = "\0";
		int		levelNo = 1;
		char	tmpInstanceNo[16]="";
		char	instanceNo[32]="";
		char	queryWhere[256] = "\0";
		//Check Msg Length
		if (pdu->var[i].msglen > MaxLenOfParaValue) {
			omcLog(paraCommLog,
				   " Msg is too long(pdu->var[%d].msglen =%d)", i,
				   pdu->var[i].msglen);
			return (0);
		}
		
		//check PreObjId
		for (j = 0; j < commArr[commNo].snmpInfo.preOidLen; j++) {
			if (commArr[commNo].snmpInfo.oid[j] != pdu->var[i].oid[j]) {
				int k = 0;
				omcLog(paraCommLog, " Oid is not match!");
				for (k = 0; k < commArr[commNo].snmpInfo.preOidLen; k++) {
					omcLog(paraCommLog, " %d: %ld [%ld]", k,
						   commArr[commNo].snmpInfo.oid[k],
						   pdu->var[i].oid[k]);
				}
				return (0);
			}
		}
		
		//check subObjId
		for (j = commArr[commNo].snmpInfo.preOidLen; j < commArr[commNo].snmpInfo.oidLen; j++) {
			if (commArr[commNo].snmpInfo.oid[j] != pdu->var[i].oid[j]) {
				if(commArr[commNo].commType==nGetBulkComm){//Finished GetBulk Table
					commArr[commNo].commState = nOutProc;
					break;
				}else
					return(0);
			}
		}
		
		if(checkMibSystem(commArr[commNo].sysTypeNo))
		{
			if(commArr[commNo].snmpInfo.columnNum!=0){//Is a table
				sprintf(updateSql,"REPLACE INTO %s SET ",commArr[commNo].paramTable);
				levelNo=1;
				for (j = commArr[commNo].snmpInfo.preOidLen; j < commArr[commNo].snmpInfo.oidLen+1;j++) {
					sprintf(tmpStr, "level_%d = '%ld',", levelNo, pdu->var[i].oid[j]);
					strcat(updateSql,tmpStr);
					levelNo++;
				}
				
				//Check instanceNo
				for(j=commArr[commNo].snmpInfo.oidLen+1;j<commArr[commNo].snmpInfo.oidLen+1+commArr[commNo].snmpInfo.instanceNoLevel;j++){
					if(commArr[commNo].snmpInfo.instanceNo[j-commArr[commNo].snmpInfo.oidLen-1]!=pdu->var[i].oid[j]&&
						commArr[commNo].snmpInfo.instanceNo[j-commArr[commNo].snmpInfo.oidLen-1]!=0){
						commArr[commNo].commState = nOutProc;
						break;
					}
				}
				
				//organize instanceNo
				for(j=commArr[commNo].snmpInfo.oidLen+1;j<pdu->var[i].oidlen;j++){
					if(j==commArr[commNo].snmpInfo.oidLen+1)
						sprintf(tmpInstanceNo, "%04ld", pdu->var[i].oid[j]);
					else
						sprintf(tmpInstanceNo, ".%04ld", pdu->var[i].oid[j]);
					strcat(instanceNo, tmpInstanceNo);
				}
				
				sprintf(tmpStr, "instanceNo='%s',",instanceNo);
				
				strcat(updateSql,tmpStr);    
			}else{
				sprintf(updateSql,"REPLACE INTO %s SET ",commArr[commNo].paramTable);   	
				levelNo=1;			
				for (j = commArr[commNo].snmpInfo.preOidLen; j < commArr[commNo].snmpInfo.oidLen;j++) {
					sprintf(tmpStr, "level_%d = '%ld',", levelNo, pdu->var[i].oid[j]);
					strcat(updateSql,tmpStr);
					levelNo++;
				}
				
				
				for(j=commArr[commNo].snmpInfo.oidLen;j<pdu->var[i].oidlen;j++){
					if(j==commArr[commNo].snmpInfo.oidLen)
						sprintf(tmpInstanceNo, "%04ld", pdu->var[i].oid[j]);
					else
						sprintf(tmpInstanceNo, ".%04ld", pdu->var[i].oid[j]);
					strcat(instanceNo, tmpInstanceNo);
				}
				
				sprintf(tmpStr, "instanceNo='%s',",instanceNo);
				strcat(updateSql,tmpStr);	
				
				
			}		
		}else{
			sprintf(updateSql,"UPDATE %s SET ",commArr[commNo].paramTable);		
							
			for (j = commArr[commNo].snmpInfo.preOidLen; j < commArr[commNo].snmpInfo.preOidLen+commArr[commNo].levelWidth[i];j++) {
				if(j==commArr[commNo].snmpInfo.preOidLen)
					sprintf(tmpStr, " WHERE level_%d = '%ld'", levelNo, pdu->var[i].oid[j]);
				else
					sprintf(tmpStr, " AND level_%d = '%ld'", levelNo, pdu->var[i].oid[j]);
				strcat(queryWhere,tmpStr);
				levelNo++;
			}
			
			for(j=commArr[commNo].snmpInfo.preOidLen+commArr[commNo].levelWidth[i];j<pdu->var[i].oidlen;j++){
				if(j==commArr[commNo].snmpInfo.preOidLen+commArr[commNo].levelWidth[i])
					sprintf(tmpInstanceNo, "%ld", pdu->var[i].oid[j]);
				else
					sprintf(tmpInstanceNo, ".%ld", pdu->var[i].oid[j]);
				strcat(instanceNo, tmpInstanceNo);
			}
					
			sprintf(tmpStr, " AND instanceNo='%s'",instanceNo);
			strcat(queryWhere,tmpStr);
		}
		
		if ((pdu->error_status > 0) && (pdu->error_index == (i + 1))) {
			omcLog(paraCommLog,
				   "Error message: pdu->error_status =%d  pdu->error_index =%d",
				   pdu->error_status, pdu->error_index);

			if (pdu->error_status < MaxErrorStatusNum) {
				sprintf(tmpStr,",`%s`='Error:%s'", updateField,
						errorStatusDescArr[pdu->error_status]);
				
			} else {
				sprintf(tmpStr,",`%s`='Error:Unknown Error'", updateField);
			}
			return (-1);
		}
		
		if(commArr[commNo].commState == nOutProc)
			break;
		
		switch (pdu->var[i].vartype) {
		case 0x02:				//INTEGER
			tmpLongInt =
				decode_integer(pdu->var[i].msg, pdu->var[i].msglen);

			sprintf(tmpStr,"`%s`='%d'", updateField,tmpLongInt);
			commArr[commNo].finishNum++;
			break;
		case 0x04:				//OCTET STRING
			if(checkMibSystem(commArr[commNo].sysTypeNo))
			{
				str_index=0;
				for(j=0;j<pdu->var[i].msglen;j++)
				{
					tmpValue[str_index]=toascii(pdu->var[i].msg[j]);
					str_index++;
					if(tmpValue[str_index-1] == '\\')
					{
						tmpValue[str_index]='\\';
						str_index++;
					}
				}
				tmpValue[str_index]=0;
			}else{
				omc_RbcdToAscii(tmpValue, pdu->var[i].msg,
								pdu->var[i].msglen * 2);
			}
			sprintf(tmpStr,"`%s`='%s'", updateField,tmpValue);
			commArr[commNo].finishNum++;
			break;
		case 0x05:				//NULL(unSpecified)
			sprintf(tmpStr,"`%s`=''", updateField);
			commArr[commNo].finishNum++;
			break;
		case 0x06:				//OBJECT IDENTIFIER
			tmpLongInt =decode_integer(pdu->var[i].msg, pdu->var[i].msglen);
			tmpLongInt =
				decode_integer(pdu->var[i].msg, pdu->var[i].msglen);

			sprintf(tmpStr,"`%s`='%d'", updateField,tmpLongInt);
			commArr[commNo].finishNum++;
			break;
		case 0x40:				//IP Address
			sprintf(tmpStr,"`%s`='%d.%d.%d.%d'", updateField,
							pdu->var[i].msg[0],pdu->var[i].msg[1],
							pdu->var[i].msg[2],pdu->var[i].msg[3]);
			commArr[commNo].finishNum++;
			break;
		case 0x44:				//Opaque
			omc_RbcdToAscii(tmpValue, pdu->var[i].msg,
								pdu->var[i].msglen * 2);
			sprintf(tmpStr,"`%s`='%s'", updateField,tmpValue);
			commArr[commNo].finishNum++;
			break;
		case 0x80:				//noSuchObject
			sprintf(tmpStr,"`%s`='Error:NoSuchObject'", updateField);
			commArr[commNo].finishNum++;
			break;
		case 0x81:				//NoSuchInstance
			sprintf(tmpStr,"`%s`='Error:NoSuchInstance'", updateField);
			commArr[commNo].finishNum++;
			break;
		case 0x82:				//endOfMibView
			commArr[commNo].commState = nOutProc;
			commArr[commNo].finishNum++;
			break;
		default:
			omcLog(paraCommLog,
				   " Invailed vartype(pdu->var[%d].vartype=%d)--> unknown var type",
				   i, pdu->var[i].vartype);
			return (-1);
		}
		
		if(commArr[commNo].commState == nOutProc)
			break;
		
		strcat(updateSql,tmpStr);
		// by simon, at 2023-11-15
		strcat(updateSql,",`initValue`=`readValue`");
		if(commArr[commNo].sysTypeNo!=320){
			strcat(updateSql,queryWhere);
		}
		//omcLog(paraCommLog,"\nupdateSql=%s\n",updateSql);
		
		//ISSUE-3, SMPP(VSS,EMS) need subSysNo
		if(checkPlatHasSubSysNo(commArr[commNo].sysTypeNo,commArr[commNo].sysNo))
		{
			sprintf(tmpStr,",subSysNo=%d",commArr[commNo].subSysNo);
			strcat(updateSql,tmpStr);
		}
		
		mysql_getnores(dbConn, updateSql);

		//if(commArr[commNo].commType!=nSetComm){
		//	sprintf(updateSql,"UPDATE %s SET initValue=readValue %s",commArr[commNo].paramTable,queryWhere);
		//	mysql_getnores(dbConn, updateSql);
		//}
	}


	if(commArr[commNo].commType == nGetBulkComm){
		if(commArr[commNo].commState != nOutProc){//Send command again
			mkAddr(commNo, &tmpAddr);
			mkPdu(commNo, pdu->var, &tmpPdu);
			commArr[commNo].waitTimeCount = 0;
			commArr[commNo].timeoutCount = 0;
			if (snmp_send(&tmpPdu, &tmpAddr) > 0) {
				commArr[commNo].procState = nWaitResponse;
			} else {
				omcLog(paraCommLog, "Send snmp message failed!(IP=%s)",
					   commArr[commNo].snmpInfo.dstIP);
				commArr[commNo].commState = nProcFail;
				sprintf(commArr[commNo].desc,CONF_COMMAND_ERR_0301);
				updateCommTable(commNo);
				commArr[commNo].procState = nIdle;
				initUnitComm(commNo);
			}
		}else{     
			freeParamSet(commNo);       
		}
	}else if (commArr[commNo].finishNum >= commArr[commNo].totalNum) {
		commArr[commNo].commState = nOutProc;
		freeParamSet(commNo);
	}
	
	return (1);
}

/*************************************************
Function:        // updateCommTable
Description:     // 将指定命令编号的信息，更新到命令表。
				 // commNo为命令编号，
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 1->ok,0->failed
Others:          // 
*************************************************/
int updateCommTable(int commNo)
{
	char tmpQuery[256] = "\0";
#if paraComm_DEBUG
	omcLog(paraCommLog, "commArr[%d].commState=%d", commNo,
		   commArr[commNo].commState);
#endif
	if (commArr[commNo].procState == nIdle) {
		sprintf(tmpQuery,
				"UPDATE %s SET `commState` = '%d',`finishNum`= '0', `totalNum`= '%d',"
				"bgnTime = CURRENT_TIMESTAMP, `remark`='%s' WHERE commId = '%d'",
				CommTable, commArr[commNo].commState,
				commArr[commNo].totalNum, commArr[commNo].desc,
				commArr[commNo].commId);
	} else {
		sprintf(tmpQuery, 
				"UPDATE %s SET `commState`='%d',`finishNum`='%d', "
				"`endTime` = CURRENT_TIMESTAMP, `remark`='%s' WHERE `commId` = '%d'",
				CommTable, commArr[commNo].commState,
				commArr[commNo].finishNum, commArr[commNo].desc,
				commArr[commNo].commId);
	}
	mysql_getnores(dbConn, tmpQuery);
	return (1);
}


/*************************************************
Function:        // getSysAddr
Description:     // 根据系统id从OMC_PUB.sysInfo表，获取该系统的ip
				 // commNo为命令编号，
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 1->ok,0->failed
Others:          // 
*************************************************/
int getSysAddr(int commNo)
{
	int nReturn = 0;
	MYSQL_RES *tmpResult;
	MYSQL_ROW tmpRow;
	char tmpQuery[512] = "\0";
	sprintf(tmpQuery,
			"SELECT isRemote,netId,DPC,ip FROM %s WHERE sysTypeNo='%d' "
			"AND sysNo='%d' AND subsysNo='%d' ", IpTable,
			commArr[commNo].sysTypeNo, commArr[commNo].sysNo,
			commArr[commNo].subSysNo);
	tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpQuery);
	if (tmpResult == NULL) {
		omcLog(paraCommLog,
			   " Database may be stopped,when get IP address from IpTable");
		return (0);
	}
	if ((tmpRow = mysql_fetch_row(tmpResult)) != NULL) {
		strcpy(commArr[commNo].snmpInfo.dstIP, tmpRow[3]);
#if paraComm_DEBUG
		//omcLog(paraCommLog, " dstIP=%s", commArr[commNo].dstIP);
#endif
		nReturn = 1;
	} else {
		nReturn = 0;
	}
	mysql_free_result(tmpResult);
	return (nReturn);
}

/*************************************************
Function:        // getParamTable
Description:     // 根据系统类型编号，系统编号，参数类型，得出表名
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 1->ok,0->failed
Others:          // 
*************************************************/
int getParamTable(int sysTypeNo, int sysNo, int paramType, char *tableName)
{
	if (paramType == nGlobalSysParam) {
		sprintf(tableName, "OBJ_%d.param_%d", sysTypeNo, nPubFlag);
	} else {
		sprintf(tableName, "OBJ_%d.param_%d", sysTypeNo, sysNo);
	}
	return (1);
}


/*************************************************
Function:        // mkVarArr
Description:     // 将指定命令的数据变量添加到snmp的数据类型var_list中，为mkPdu做准备。\
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           //命令编号，pdu中的var_list的指针。 
Output:          // 
Return:          // 1->ok,0->failed
Others:          // 
*************************************************/
int mkVarArr(int commNo, var_list * varArr)
{
	int i,tmpColumnNo;
	
	MYSQL_ROW tmpRow;
	int nInstanceNo= 10;
	int nInitValue = 11;
	int nReadValue = 12;
	int nValueType = 13;
	int nLengthInTemplate=15;
	
	var_list *unitVar;
	int varCount = 0;
	int unitVarLen = 0;
	int unitVarMsgLen = 0;
	int msgLen = 0;
	long tmpInt = 0;
	
	char *oneInstanceNo;

	if(checkMibSystem(commArr[commNo].sysTypeNo))
	{
		if(commArr[commNo].commType==nGetBulkComm){	
			for(tmpColumnNo=0;tmpColumnNo<commArr[commNo].snmpInfo.columnNum;tmpColumnNo++){
				unitVar = varArr + varCount;
				
				//objId
				for (i = 0; i< commArr[commNo].snmpInfo.oidLen; i++) {
					unitVar->oid[i] = commArr[commNo].snmpInfo.oid[i];
				}
				unitVar->oidlen = commArr[commNo].snmpInfo.oidLen;		
				
				//Column
				unitVar->oid[unitVar->oidlen] = commArr[commNo].snmpInfo.column[tmpColumnNo];
				unitVar->oidlen++;
				
				//Instance
				for (i = 0; i < commArr[commNo].snmpInfo.instanceNoLevel; i++) {
					unitVar->oid[unitVar->oidlen+i] = commArr[commNo].snmpInfo.instanceNo[i];
				}
				
				unitVar->oidlen = unitVar->oidlen+commArr[commNo].snmpInfo.instanceNoLevel;
				unitVar->msglen = 0;
#if paraComm_DEBUG			   
				omcLog(paraCommLog,"unitVar->oidlen=%d", unitVar->oidlen);		
				for(i=0;i<unitVar->oidlen;i++){
					omcLog(paraCommLog,"unitVar->oid=%d", unitVar->oid[i]);		
				}
#endif			
				varCount++;
			}      
		}else{
			//sql="SELECT level_1,...level_10,instanceNo,readValue,initValue,valueType FROM %s WHERE %s
			//field define
			if (commArr[commNo].paramSet == NULL) {
				omcLog(paraCommLog, "Error: commArr[%d].paramSet == NULL", commNo);
				return (0);
			}
	    	
			mysql_data_seek(commArr[commNo].paramSet, commArr[commNo].finishNum);
			while ((varCount < MaxVarNum)
				   && (tmpRow = mysql_fetch_row(commArr[commNo].paramSet))) {
				
				//if(strcmp(tmpRow[nReadValue],tmpRow[nInitValue])==0&&commArr[commNo].commType == nSetComm){
				//	commArr[commNo].finishNum++;
				//	continue;
				//}
				
				//AdministrationState do not set
				if(commArr[commNo].commType == nSetComm && commArr[commNo].snmpInfo.columnNum > 0)
				{
					if(strstr(tmpRow[14],"AdministrationState") || strstr(tmpRow[14],"CreateEntry"))
					{
						commArr[commNo].finishNum++;
						continue;
					}
				}

				//Command do not set
				if(commArr[commNo].commType == nSetComm && commArr[commNo].snmpInfo.columnNum > 0 && strstr(tmpRow[14],"Command"))
				{
					commArr[commNo].finishNum++;
					continue;
				}
				
				unitVarMsgLen = strlen(tmpRow[nInitValue]);
				
				unitVarLen =
					commArr[commNo].snmpInfo.oidLen + commArr[commNo].snmpInfo.instanceNoLevel + unitVarMsgLen;
	        	
				if (unitVarLen > (commArr[commNo].snmpInfo.maxMsgLen - msgLen)) {
					break;
				}
				unitVar = varArr + varCount;
				
				for (i = 0; i < commArr[commNo].snmpInfo.preOidLen; i++) {
					unitVar->oid[i] = commArr[commNo].snmpInfo.oid[i];
				}
				unitVar->oidlen = commArr[commNo].snmpInfo.preOidLen;
				
				//level_1,....level_10
				i=0;
				while ((atoi(tmpRow[i]) > 0) && ((i + unitVar->oidlen)< MaxOidLen)) {
					unitVar->oid[i+unitVar->oidlen] = atoi(tmpRow[i]);
					i++;
				}
				commArr[commNo].levelWidth[varCount]=(BYTE)i;
				unitVar->oidlen=unitVar->oidlen+i;
					
				if(commArr[commNo].snmpInfo.instanceNoLevel>0){
					for (i = 0; i < commArr[commNo].snmpInfo.instanceNoLevel; i++) {
						unitVar->oid[i+unitVar->oidlen] = commArr[commNo].snmpInfo.instanceNo[i];
					}
					unitVar->oidlen = unitVar->oidlen + commArr[commNo].snmpInfo.instanceNoLevel;
				}else{
					i=0;
					while ((oneInstanceNo = strsep(&(tmpRow[nInstanceNo]), ".")) != NULL) {
						unitVar->oid[unitVar->oidlen] = atoi(oneInstanceNo);
						i++;
					}
					unitVar->oidlen = unitVar->oidlen + i;
				}

				// fj modify
				int key_val_type = atoi(tmpRow[nValueType]);
				if(strstr(tmpRow[14], "RowStatus") != NULL && key_val_type == 0)
				{
					
					key_val_type = TYPE_INTEGER;

					omcLog(paraCommLog, " change from 0 to %d", TYPE_INTEGER);
				}
				
				switch (key_val_type){
					case TYPE_INTEGER:
					case TYPE_INTEGER32:
					case TYPE_UNSIGNED32:
					case TYPE_UINTEGER:
					case TYPE_BITSTRING:
						unitVar->vartype = 0x02; 
						tmpInt = atol(tmpRow[nInitValue]);
						unitVar->msglen = encode_integer(unitVar->msg, tmpInt);
						break;     
					case TYPE_OCTETSTR:
					case TYPE_NSAPADDRESS:  
						unitVar->vartype = 0x04; 
						memcpy(unitVar->msg, tmpRow[nInitValue],
											strlen(tmpRow[nInitValue]));
						unitVar->msglen = strlen(tmpRow[nInitValue]);
						
						break;  
					case TYPE_NULL:
						break;    			
    				case TYPE_NETADDR:      
    				case TYPE_IPADDR:
    					unitVar->vartype = 0x40; 
    					tmpInt=inet_addr(tmpRow[nInitValue]);
    					memcpy(unitVar->msg, &tmpInt,4);	
						unitVar->msglen = 4;   
    					break;
    				case TYPE_COUNTER: 
    				case TYPE_COUNTER64:
    					break;     
    				case TYPE_GAUGE:
    					break;        
    				case TYPE_TIMETICKS:
    					break;    
    				case TYPE_OPAQUE:
    					unitVar->vartype = 0x44; 
    					omc_AsciiToRbcd(unitVar->msg, tmpRow[nInitValue],
										strlen(tmpRow[nInitValue]));
							unitVar->msglen = strlen(tmpRow[nInitValue])/2;
							if(strlen(tmpRow[nInitValue])%2 == 1)
								unitVar->msglen++;
    					break;  
    				default:
    					omcLog(paraCommLog, " Invailed vartype=%d",
						   nValueType);
						return (0);
    					break;   	    			 
				}
				
				
				sprintf(commArr[commNo].readValue[varCount],tmpRow[nReadValue]);
				msgLen += (unitVar->oidlen + unitVar->msglen + 2);
#if paraComm_DEBUG
				omcLog(paraCommLog, " varArr[%d].oidlen=%d", varCount,
					   varArr[varCount].oidlen);
				omcLog(paraCommLog, " varArr[%d].objId=", varCount);
				for (i = 0; i < varArr[varCount].oidlen; i++) {
					omcLog(paraCommLog, "%ld.", varArr[varCount].oid[i]);
				}
				omcLog(paraCommLog, " varArr[%d].vartype=%d", varCount,
					   varArr[varCount].vartype);
				omcLog(paraCommLog, " varArr[%d].msglen=%d", varCount,
					   varArr[varCount].msglen);
				for (i = 0; i < varArr[varCount].msglen; i++) {
					omcLog(paraCommLog, " varArr[%d].msg[%d]=%x", varCount, i,
						   varArr[varCount].msg[i]);
				}
				omcLog(paraCommLog, " filled message len=%d", msgLen);
#endif
				varCount++;
				if (commArr[commNo].snmpInfo.needMuliObj < 1) {
					break;
				}
			}							//end of while(..)	
		}		
	}else{	
		//sql="SELECT level_1,...level_10,instanceNo,readValue,initValue,valueType FROM %s WHERE %s
		//field define
		if (commArr[commNo].paramSet == NULL) {
			omcLog(paraCommLog, "Error: commArr[%d].paramSet == NULL", commNo);
			return (0);
		}
	
		mysql_data_seek(commArr[commNo].paramSet, commArr[commNo].finishNum);
		while ((varCount < MaxVarNum)
			   && (tmpRow = mysql_fetch_row(commArr[commNo].paramSet))) {
			
			//if(strcmp(tmpRow[nReadValue],tmpRow[nInitValue])==0&&commArr[commNo].commType == nSetComm){
			//	commArr[commNo].finishNum++;
			//	continue;
			//}
			
			//unitVarMsgLen = strlen(tmpRow[nInitValue]);
			//unitVarMsgLen = strlen(tmpRow[nInitValueTemplate]);
			unitVarMsgLen=atoi(tmpRow[nLengthInTemplate]);
			unitVarLen =
				commArr[commNo].snmpInfo.oidLen + commArr[commNo].snmpInfo.instanceNoLevel + unitVarMsgLen;
	
			if (unitVarLen > (commArr[commNo].snmpInfo.maxMsgLen - msgLen)) {
				break;
			}
			unitVar = varArr + varCount;
			
			for (i = 0; i < commArr[commNo].snmpInfo.preOidLen; i++) {
				unitVar->oid[i] = commArr[commNo].snmpInfo.oid[i];
			}
			unitVar->oidlen = commArr[commNo].snmpInfo.preOidLen;
			
			//level_1,....level_10
			i=0;
			while ((atoi(tmpRow[i]) > 0) && ((i + unitVar->oidlen)< MaxOidLen)) {
				unitVar->oid[i+unitVar->oidlen] = atoi(tmpRow[i]);
				i++;
			}
			commArr[commNo].levelWidth[varCount]=(BYTE)i;
			unitVar->oidlen=unitVar->oidlen+i;
				
			if(commArr[commNo].snmpInfo.instanceNoLevel>0){
				for (i = 0; i < commArr[commNo].snmpInfo.instanceNoLevel; i++) {
					unitVar->oid[i+unitVar->oidlen] = commArr[commNo].snmpInfo.instanceNo[i];
				}
				unitVar->oidlen = unitVar->oidlen + commArr[commNo].snmpInfo.instanceNoLevel;
			}else{
				i=0;
				while ((oneInstanceNo = strsep(&(tmpRow[nInstanceNo]), ".")) != NULL) {
					unitVar->oid[unitVar->oidlen] = atoi(oneInstanceNo);
					i++;
				}
				unitVar->oidlen = unitVar->oidlen + i;
			}
			
			unitVar->vartype = atoi(tmpRow[nValueType]); 
			switch (atoi(tmpRow[nValueType])) {
				case 0x02:			//INTEGER
					tmpInt = atol(tmpRow[nInitValue]);
					unitVar->msglen = encode_integer(unitVar->msg, tmpInt);
					//unitVar->msglen = strlen(tmpRow[nInitValue]);
					break;
				case 0x04:			//OCTET STRING
					omc_AsciiToRbcd(unitVar->msg, tmpRow[nInitValue],
									strlen(tmpRow[nInitValue]));
					//unitVar->msglen = strlen(tmpRow[nInitValue])/2;
					//unitVar->msglen = strlen(tmpRow[nInitValueTemplate])/2;
					unitVar->msglen = atoi(tmpRow[nLengthInTemplate]);
					break;
				case 0x05:			//NULL(unSpecified)
				case 0x06:			//OBJECT IDENTIFIER
				case 0x80:			//noSuchObject
				case 0x81:			//NoSuchInstance
				case 0x82:			//endOfMibView
				default:
					omcLog(paraCommLog, " Invailed vartype=%d",
						   unitVar->vartype);
					return (0);
			}
			
			
			sprintf(commArr[commNo].readValue[varCount],tmpRow[nReadValue]);
			msgLen += (unitVar->oidlen + unitVar->msglen + 2);
#if paraComm_DEBUG
			omcLog(paraCommLog, " varArr[%d].oidlen=%d", varCount,
				   varArr[varCount].oidlen);
			omcLog(paraCommLog, " varArr[%d].objId=", varCount);
			for (i = 0; i < varArr[varCount].oidlen; i++) {
				omcLog(paraCommLog, "%ld.", varArr[varCount].oid[i]);
			}
			omcLog(paraCommLog, " varArr[%d].vartype=%d", varCount,
				   varArr[varCount].vartype);
			omcLog(paraCommLog, " varArr[%d].msglen=%d", varCount,
				   varArr[varCount].msglen);
			for (i = 0; i < varArr[varCount].msglen; i++) {
				omcLog(paraCommLog, " varArr[%d].msg[%d]=%x", varCount, i,
					   varArr[varCount].msg[i]);
			}
			omcLog(paraCommLog, " filled message len=%d", msgLen);
#endif
			varCount++;
			if (commArr[commNo].snmpInfo.needMuliObj < 1) {
				break;
			}
		}							//end of while(..)	
	}

	commArr[commNo].varNum = varCount;
	
	return (1);
}

/*************************************************
Function:        // mkAddr
Description:     // 合成指定命令的snmp地址，从该命令的数据结构中可取出ip和端口，为发送和接收snmp消息做准备。
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           //命令编号，snmp_addr的指针。 
Output:          // 
Return:          // 1->ok,0->failed
Others:          // 
*************************************************/
int mkAddr(int commNo, snmp_addr * msgAddr)
{
#if paraComm_DEBUG
	omcLog(paraCommLog, "\n Initing message address----");
	omcLog(paraCommLog, " addr->local_port:%d", DefPort);
	//omcLog(paraCommLog, " addr->remote_ip:%s", commArr[commNo].dstIP);
	//omcLog(paraCommLog, " addr->remote_port:%d", commArr[commNo].dstPort);
#endif

	//make snmp address
	if (strlen(commArr[commNo].snmpInfo.dstIP) <= 0) {
		omcLog(paraCommLog, "Initing snmp_addr error: Cannot get ip");
		sprintf(commArr[commNo].desc, CONF_COMMAND_ERR_0102);
		commArr[commNo].commState = nProcFail;
		updateCommTable(commNo);
		commArr[commNo].procState = nIdle;
		return (0);
	}
	//addr->local_ip    = ;
	msgAddr->local_port = DefPort;
	msgAddr->remote_ip = inet_addr(commArr[commNo].snmpInfo.dstIP);
	msgAddr->remote_port = commArr[commNo].snmpInfo.dstPort;
	msgAddr->broadcast = 0;
	return (1);
}

/*************************************************
Function:        // mkPdu
Description:     // 合成指定命令的snmp数据包，为snmp_send做准备。
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           //命令编号，var_list的指针，snmp_pdu的指针。 
Output:          // 
Return:          // 1->ok,0->failed
Others:          // 
*************************************************/
int mkPdu(int commNo, var_list * varArr, snmp_pdu * pdu)
{
	BYTE pduType;
#if paraComm_DEBUG
	omcLog(paraCommLog, " Making snmp_pdu");
#endif
	switch (commArr[commNo].commType) {
	case nGetComm:
		pduType = PDU_GET ;
		break;
	case nSetComm:
	case nNewEntryComm:
		pduType = PDU_SET;
		break;
	case nGetBulkComm:
		pduType = PDU_GETNEXT;
		break;
	default:
		return (0);
	}
	pdu->pdu_type = pduType;
	pdu->request_id = commArr[commNo].commId;
	pdu->var_num = commArr[commNo].varNum;
	sprintf(pdu->community, "%s", commArr[commNo].snmpInfo.snmpCommunity);

	memcpy(pdu->var, varArr, sizeof(var_list) * BIND_MAX);
#if paraComm_DEBUG
	omcLog(paraCommLog, " memcpy finished!");
#endif
	pdu->error_status = 0x0;	//0:no error 1:too big 2:nosuchname 3:badvalue 4:readonly 5:agenerr
	pdu->error_index = 0x0;
	return (1);
}

/*************************************************
Function:        // initUnitComm
Description:     // 初始化指定命令，将该命令数据初始化，并释放未释放的结果集。
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           //命令编号
Output:          // 
Return:          // 1->ok,0->failed
Others:          // 
*************************************************/
int initUnitComm(int commNo)
{
	int i = 0;
#if paraComm_DEBUG
	omcLog(paraCommLog, " Try to init commArr[%d] ", commNo);
#endif
	if (commNo > MaxCommNum) {
		return (0);
	}
	commArr[commNo].commId = 0;
	commArr[commNo].commType = 0;
	commArr[commNo].paramType = 0;
	commArr[commNo].sysTypeNo = 0;
	commArr[commNo].sysNo = 0;
	commArr[commNo].subSysNo = 0;

	freeParamSet(commNo);
#if paraComm_DEBUG
	omcLog(paraCommLog," commArr[%d].paramSet = %x",commNo,commArr[commNo].paramSet);
#endif
	commArr[commNo].totalNum = 0;
	commArr[commNo].finishNum = 0;
	commArr[commNo].desc[0] = 0;
	commArr[commNo].paramTable[0] = 0;

	commArr[commNo].snmpInfo.needMuliObj = 0;
	commArr[commNo].snmpInfo.dstIP[0] = 0;
	commArr[commNo].snmpInfo.dstPort = DefPort;
	commArr[commNo].snmpInfo.oidLen = 0;
	for (i = 0; i < MaxOidLen; i++) {
		commArr[commNo].snmpInfo.oid[i] = 0;
	}
	
	commArr[commNo].snmpInfo.instanceNoLevel = 0;
	for (i = 0; i < MaxInstanceNoLevel; i++) {
		commArr[commNo].snmpInfo.instanceNo[i] = 0;
	}
	
	commArr[commNo].snmpInfo.snmpCommunity[0] = 0;
	
	commArr[commNo].commState = 0;
	commArr[commNo].procState = 0;
	commArr[commNo].waitTimeCount = 0;
	commArr[commNo].timeoutCount = 0;
	
	commArr[commNo].varNum = 0;
	
#if paraComm_DEBUG
	omcLog(paraCommLog, " init commArr[%d] ok", commNo);
#endif
	return (1);
}


/*************************************************
Function:        // freeParamSet
Description:     // check and free commArr[commNo].paramSet
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           //命令编号
Output:          // 
Return:          // 
Others:          // 
*************************************************/

void freeParamSet(int commNo)
{
	int i;
	if (commArr[commNo].paramSet != NULL) {
		int isCanFree = 1;
		//because same sql's resultSet's address will be same,so it is must check other command's state 
		for (i = 0; i < MaxCommNum; i++) {
			if ((i != commNo)
				&& (commArr[i].paramSet == commArr[commNo].paramSet)) {
				if ((commArr[i].commState == nWaitProc)
					|| (commArr[i].commState == nInProc)) {
					isCanFree = 0;
				} else {
					//omcLog(paraCommLog," Set commArr[%d].paramSet (%x) = NULL",i,commArr[i].paramSet);
					commArr[i].paramSet = NULL;
				}
			}
		}
		if (isCanFree > 0) {
#if paraComm_DEBUG
			//omcLog(paraCommLog," Try to free commArr[%d].paramSet (%x)",commNo,commArr[commNo].paramSet);
#endif
			mysql_free_result(commArr[commNo].paramSet);
		}
		commArr[commNo].paramSet = NULL;
	}
}

void optErr(unitComm *ucomm)
{			
	int ii;			
	char where[128];
	char updatesql[256];
	char instanceList[32];
	char tmp[16];
	int ilen;
	int ioid;
	
	memset(instanceList,0,32);
	for(ii=0;ii<ucomm->snmpInfo.instanceNoLevel;ii++)
	{
		sprintf(tmp,"%04d.",ucomm->snmpInfo.instanceNo[ii]);
		strcat(instanceList,tmp);
	}
	ilen=strlen(instanceList);
	if(instanceList[ilen-1] == '.')
		instanceList[ilen-1]='\0';

		
	//printf("\n");
	//printf("instanceNo=%s\n",instanceList);
	memset(where,0,128);
	strcat(where,"where ");
	ioid=1;
	for(ii=ucomm->snmpInfo.preOidLen;ii<ucomm->snmpInfo.oidLen;ii++)
	{
		//printf("%d ",ucomm->snmpInfo.oid[ii]);
		sprintf(tmp,"level_%d=%d and ",ioid++,ucomm->snmpInfo.oid[ii]);
		strcat(where,tmp);
	}
	sprintf(tmp,"instanceNo='%s' ",instanceList);
	strcat(where,tmp);
	//printf("\nwhere=%s\n",where);
	//printf("paramTable=%s\n",ucomm->paramTable);
	sprintf(updatesql, "update %s set `initValue`=`readValue` %s",ucomm->paramTable,where);
	mysql_getnores(dbConn, updatesql);
	omcLog(paraCommLog, "opt error,sql=%s",updatesql);
}	
