/*************************************************
File name:	smeg.c
Author: 	JianHui Zheng
Version:	9:00:00 
Date:  		2008-4-1
Description:This file include functions of smeg
			
			
			
												
History:               
No. 		
Author:		  
Date:		 
Version:	   
Description:
*************************************************/
#include "include/statistic_data.h"
#include <sys/time.h>
//#include "../../plat/snmp/src/include/snmp.h"
#include "snmp.h"
//#include "src/include/smeg_pub.h"
//#include "smeg_pub.h"

#define BYTE  unsigned char
#define OMC_STATUS_SLAVE 3
#define OMC_STATUS_MASTER 5
#define OMC_STATUS_SINGLE 7

extern int dba_conn_thread(void *param);

void set_license(int n);
extern int max_license_count;
extern BYTE omc_sequeue[2][4];
//extern BYTE DEBUG_buf[512];
int getOmcSysNo(int* sysNo);

/* by simon at 23/9/26 */
extern int omcSysNo;

int omcStatus=-1;
#define counts_per_h (50*3600)

static struct call_statistics Statistic_data;
static int time_num;
static struct cdr CDR[2000];
static int cdr_num;
#define time_printf  500
BYTE *SequenceNum = NULL;
int systemID = 0;

//DWORD	remote_ip;
#define HEART_BEATING_PORT 4957

DWORD SMEG_OID_PREFIX[20]={1,3,6,1,4,1,1373,2,3,3,11,9};
extern DWORD smeg_ip[2];
extern int omc_status[2];

extern int smeg_writeParam();
extern inline BYTE get_function_flag();
extern void exitLog(const char *fmt, ...);
struct smeg_heartbeat
{
	BYTE	systemID;
	BYTE	subSystemID;
	BYTE  timeStamp[4];
	BYTE	LED[8];
	BYTE 	Component[2];
	BYTE	Alarm_code;
	BYTE 	length_1[2];
	BYTE 	Compenent_id[2];
	BYTE 	length_2[2];
	BYTE	software_version[3];
	BYTE	state;
	BYTE	parameter_check_sum[4]; 
	BYTE 	max_user_licesnses[4];
	BYTE	imported_online_users[4];
	BYTE	sequenceNum[4];
	BYTE	SMPP_TX_status;
	BYTE	SMPP_RX_status; 
	BYTE	SMTP_TX_status;
	BYTE	SMTP_RX_status;	
};

int save_smeg_param_flag;

//struct smeg_heartbeat smeg_heartbeat;
/*************************************************
Function:        // smeg_init
Description:     // The initial function of the smeg
Calls:           // smeg_mib_init
					smeg_debugInit
					smtp_init
					smpp_init
					set_license
Called By:       // omcMain
Table Accessed:  // 
Table Updated:   // 
Input:           // sequenceNum:sequence number of the omc
					sysNo:the system no of the omc
					subSysNo:the subsystem no of the omc
					license:the license of the smeg
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void smeg_init(BYTE *sequenceNum, int sysNo,int subSysNo, int license)
{
	SequenceNum = sequenceNum;
	systemID = sysNo;
  	smeg_mib_init();
	smeg_debugInit();
	smeg_ip[0] = 0;	//set to localhost
	smeg_ip[1] = 0;	//set to localhost
	smtp_init();
	smpp_init();
	
	getOmcSysNo(&omcSysNo);
	
	time_num = 0;
  	memset(&Statistic_data, 0, sizeof(struct call_statistics));	
  
  	cdr_num = 0;
  	memset(CDR, 0, sizeof(struct cdr )*2000);
  	save_smeg_param_flag=0;
	set_license(license);

	pthread_t tid;
	pthread_create(&tid,NULL,dba_conn_thread, NULL);
}

/*************************************************
Function:        // smeg_main
Description:     // The timer function of the smeg
Calls:           // smtp_main
					smpp_main
					smeg_debugTimer
					smeg_SendHeartBeating
Called By:       // omcMain
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void smeg_main()
{
	static BYTE time_count;
	
	if(get_function_flag())
	{
		smtp_main();	
		smpp_main();
	}
	smeg_debugTimer();	

	time_count++;
	if(time_count >= 99)  //10 sec 
	{
		
		if(save_smeg_param_flag)
			smeg_writeParam();
		//printf("omcSysNo=%d,omcstatus[0]=%d,omcstatus[1]=%d\n",omcSysNo,omc_status[0],omc_status[1]);
		
		if(omc_status[0] == OMC_STATUS_SINGLE)
		{
			smeg_SendHeartBeating(omcSysNo);
		}
		else if(omc_status[1] == OMC_STATUS_SINGLE)
		{
			smeg_SendHeartBeating(omcSysNo);
		}
		else if(omc_status[1] == OMC_STATUS_SLAVE && omcSysNo == 1)
		{
			smeg_SendHeartBeating(0);
			smeg_SendHeartBeating(1);
		}
		
		time_count = 0;
	}
}

/*************************************************
Function:        // add_call_statistics
Description:     // Statistic the csta data
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // flag:csta type; data_size:data size
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void add_call_statistics(int flag, int data_size)
{
	if(flag == Email_Outgoing_Attempt)  
		Statistic_data.Email_Outgoing.Attempt++;
	else if(flag == Email_Outgoing_Successful)
	{
		Statistic_data.Email_Outgoing.Successful++;         //Email 发送成功次数
	  Statistic_data.Email_Outgoing.Total_Bytes += data_size;
	}
	else if(flag == Email_Incoming_Attempt)
		Statistic_data.Email_Incoming.Attempt++;
	else if(flag == Email_Incoming_Successful)
	{
		Statistic_data.Email_Incoming.Successful++;   //收取Email成功次数
		Statistic_data.Email_Incoming.Total_Bytes +=  data_size;
		
	}
	else if(flag == SMS_Incoming_Attempt)
		Statistic_data.SMS_From_SMSC.Attempt++;
	else if(flag == SMS_Incoming_Successful)
	{
		Statistic_data.SMS_From_SMSC.Successful++;
		Statistic_data.SMS_From_SMSC.Total_Bytes += data_size;
  	}
	else if(flag == SMS_Outgoing_Attempt)
		Statistic_data.SMS_To_SMSC.Attempt++;
	else if(flag == SMS_Outgoing_Successful)
	{
		Statistic_data.SMS_To_SMSC.Successful++;        
		Statistic_data.SMS_To_SMSC.Total_Bytes += data_size;
	}
	else if(flag == Email_Outgoing_Failure)  
		Statistic_data.Email_Outgoing.Failure++;    //
	else if(flag == Email_Incoming_Failure)
		Statistic_data.Email_Incoming.Failure++;
}

/*************************************************
Function:        // add_CDR
Description:     // Statistic the cdr data
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // cdr_record:the cdr data
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void add_CDR(struct cdr cdr_record)
{
	strcpy((char*)CDR[cdr_num].Sender, (char*)cdr_record.Sender);
	strcpy((char*)CDR[cdr_num].Recipient, (char*)cdr_record.Recipient);
	//CDR[cdr_num].Total_bytes = cdr_record.Total_bytes;
	//CDR[cdr_num].serviceCentre = 
	//CDR[cdr_num].Email_Ref_ID
	CDR[cdr_num].recordType = cdr_record.recordType;
	CDR[cdr_num].Result = cdr_record.Result;
	strcpy(CDR[cdr_num++].Deliver_Time, cdr_record.Deliver_Time);
	if(cdr_num >= 2000)	cdr_num = 0;
	smeg_print("\t%d\t%s\n", CDR[cdr_num - 1].Result, CDR[cdr_num - 1].Deliver_Time);
}

/*************************************************
Function:        // smeg_SendHeartBeating
Description:     // Send the heartbeat to the omc
Calls:           // uIntToByte; snmp_send;
Called By:       // smeg_main
Table Accessed:  // 
Table Updated:   // 
Input:           // i:the plat no
Output:          // 
Return:          // 
Others:          // 
*************************************************/
int smeg_SendHeartBeating(int i)
{
	struct smeg_heartbeat smeg_heartbeat;
	unsigned long tmpTimestamp;
	
	snmp_pdu     snmpbuf;
	snmp_addr	 snmpaddr;
	var_list	 *varlist;
	int ret = -1;

	
	//check the ems heartbeat sequenceNum with the SequenceNum
	if(memcmp(omc_sequeue[i],SequenceNum,4) != 0)
		return 0;
		
	if(smeg_ip[i] == 0)
		return 0;	
		
  	snmpbuf.pdu_type = 0x07; //trap 
	snmpbuf.var_num	 = 0x01;

	snmpaddr.remote_ip = smeg_ip[i];
	snmpaddr.remote_port = HEART_BEATING_PORT; //4957
	snmpaddr.local_port  = HEART_BEATING_PORT;
	snmpaddr.broadcast   = 0x00;

	varlist = snmpbuf.var;
	varlist->oidlen   = 12;
	varlist->vartype  = 0x04;
	
	memcpy(&varlist->oid, SMEG_OID_PREFIX, 12*4);
	varlist->oid[12] = 0x01; /* heartbeat */
 	varlist->msglen  = sizeof(struct smeg_heartbeat);
  
	smeg_heartbeat.systemID = systemID;
	smeg_heartbeat.subSystemID = 0; 
	tmpTimestamp = time(NULL);
	uIntToByte(smeg_heartbeat.timeStamp, sizeof(smeg_heartbeat.timeStamp), tmpTimestamp);
	memset(smeg_heartbeat.LED, 0xFF, 8);
	smeg_heartbeat.Component[0] = 0;
	smeg_heartbeat.Component[1] = 0;
	
	smeg_heartbeat.Alarm_code = 0;
	
	if(get_smtp_link_state() == 0)
		smeg_heartbeat.Alarm_code = 3;
	
	if(get_smpp_tx_link_state() == 0)
		smeg_heartbeat.Alarm_code = 1;
		
	if(get_smpp_rx_link_state() == 0)
		smeg_heartbeat.Alarm_code = 2;
		
	if(!get_function_flag())
		smeg_heartbeat.Alarm_code = 0;
	/*
	if(get_smtp_link_state() == 0 
	|| get_smpp_tx_link_state() == 0
	|| get_smpp_rx_link_state() == 0)
		smeg_heartbeat.Alarm_code = 1;
	else
		smeg_heartbeat.Alarm_code = 0;
	*/
	
	smeg_heartbeat.length_1[0] = 0;
	smeg_heartbeat.length_1[1] = 25;
	smeg_heartbeat.Compenent_id[0] = 0;
	smeg_heartbeat.Compenent_id[1] = 0;
	smeg_heartbeat.length_2[0] = 0;
	smeg_heartbeat.length_2[1] = 21;
	smeg_heartbeat.software_version[0] = 1;
	smeg_heartbeat.software_version[1] = 0;
	smeg_heartbeat.software_version[2] = 1;
	
	if(get_smpp_tx_link_state() == 0 && get_smtp_link_state() == 0)
		smeg_heartbeat.state = 4;
	else
		smeg_heartbeat.state = 0;
	
	smeg_heartbeat.max_user_licesnses[0] = get_license() >> 24;
	smeg_heartbeat.max_user_licesnses[1] = (get_license() >> 16) & 0xFF;
	smeg_heartbeat.max_user_licesnses[2] = (get_license() >> 8) & 0xFF;
	smeg_heartbeat.max_user_licesnses[3] = get_license() & 0xFF;
	
	smeg_heartbeat.imported_online_users[0] = max_license_count >> 24;
	smeg_heartbeat.imported_online_users[1] = (max_license_count >> 16) & 0xFF;
	smeg_heartbeat.imported_online_users[2] = (max_license_count >> 8) & 0xFF;
	smeg_heartbeat.imported_online_users[3] = max_license_count & 0xFF;
	memcpy(smeg_heartbeat.sequenceNum, SequenceNum, 4);

	if(get_smpp_tx_link_state() == 0)
		smeg_heartbeat.SMPP_TX_status = 4;
	else 
		smeg_heartbeat.SMPP_TX_status = 0;	
			
	if(get_smpp_rx_link_state() == 0)		
		smeg_heartbeat.SMPP_RX_status = 4;
	else
		smeg_heartbeat.SMPP_RX_status = 0; 
		
	if(get_smtp_link_state() == 0){
		smeg_heartbeat.SMTP_TX_status = 4;
		smeg_heartbeat.SMTP_RX_status = 4;	
	}
	else{
		smeg_heartbeat.SMTP_TX_status = 0;
		smeg_heartbeat.SMTP_RX_status = 0;
	}	

	memcpy(varlist->msg, (BYTE *)&smeg_heartbeat, sizeof(struct smeg_heartbeat));
	
	ret = snmp_send(&snmpbuf,&snmpaddr);
	
 	return 1;
}

/*************************************************
Function:        // GetCSTA_Record
Description:     // Get the csta record
Calls:           // 
Called By:       // smeg_getmib
Table Accessed:  // 
Table Updated:   // 
Input:           // instance:the instance no; pdata:the csta data
Output:          // 
Return:          // 
Others:          // 
*************************************************/
int GetCSTA_Record(BYTE instance, BYTE *pdata)
{
	char temp_int[4];
	
	uIntToByte(pdata, 4, time(NULL));
	
 	memcpy(temp_int, &Statistic_data.Email_Incoming.Attempt, 4);
	pdata[4] = temp_int[3];
	pdata[5] = temp_int[2];
	pdata[6] = temp_int[1];
	pdata[7] = temp_int[0];
 
	memcpy(temp_int, &Statistic_data.Email_Incoming.Successful, 4);
	pdata[8] = temp_int[3];
	pdata[9] = temp_int[2];
	pdata[10] = temp_int[1];
	pdata[11] = temp_int[0];
	
	memcpy(temp_int, &Statistic_data.Email_Outgoing.Attempt, 4);	
	pdata[12] = temp_int[3];
	pdata[13] = temp_int[2];
	pdata[14] = temp_int[1];
	pdata[15] = temp_int[0];

	memcpy(temp_int, &Statistic_data.Email_Outgoing.Successful, 4);		
	pdata[16] = temp_int[3];
	pdata[17] = temp_int[2];
	pdata[18] = temp_int[1];
	pdata[19] = temp_int[0];
	
	memcpy(temp_int, &Statistic_data.SMS_From_SMSC.Attempt, 4);	
	pdata[28] = temp_int[3];
	pdata[29] = temp_int[2];
	pdata[30] = temp_int[1];
	pdata[31] = temp_int[0];

	memcpy(temp_int, &Statistic_data.SMS_From_SMSC.Successful, 4);		
	pdata[32] = temp_int[3];
	pdata[33] = temp_int[2];
	pdata[34] = temp_int[1];
	pdata[35] = temp_int[0];
	
	memcpy(temp_int, &Statistic_data.SMS_To_SMSC.Attempt, 4);
	pdata[20] = temp_int[3];
	pdata[21] = temp_int[2];
	pdata[22] = temp_int[1];
	pdata[23] = temp_int[0];
	
	memcpy(temp_int, &Statistic_data.SMS_To_SMSC.Successful, 4);
	pdata[24] = temp_int[3];
	pdata[25] = temp_int[2];
	pdata[26] = temp_int[1];
	pdata[27] = temp_int[0];

	memset(&Statistic_data, 0, sizeof(Statistic_data));

	return 36;
}

/*************************************************
Function:        // getOmcSysNo
Description:     // Get the sysNo of the local omc system 
Calls:           // 
Called By:       // cdr_init;
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // sysNo:the sysNo of the local omc
Return:          // 1:SUCCESSFUL; 0:FAIL;
Others:          // 
*************************************************/
int getOmcSysNo(int* sysNo)
{
	char fileName[512];
	unsigned char buf[4096];
	unsigned char param[32][512];
	char paramName[128];
	char paramValue[384];
	char* temp;
	FILE* fp;
	int fi;
	int i;
	//int j;
	int paramCount;
	int byteCount;
	
	paramCount=0;
	byteCount=0;
	memset(buf,0,4096);
	memset(param,0,32*512);
	sprintf(fileName,"./conf/omcd.conf");
	fp=fopen(fileName,"r");
	if(fp)
	{
		fi=fileno(fp);
		if(read(fi,buf,4096))
		{
			for(i=0;i<4096;i++)
			{	
				if(buf[i] == 0x0A)
				{
					//printf("\n");
					if(byteCount<512 && param[paramCount][0] != 0x00 && param[paramCount][0] != 0x23)
						paramCount++;
					else
						memset(param[paramCount],0,512);	
					byteCount=0;
				}	
				else
				{	
					param[paramCount][byteCount]=buf[i];
					byteCount++;
				}
				
				//printf("%02x ",buf[i]);
			}
			
			for(i=0;i<paramCount;i++)
			{
				temp=strtok((char*)param[i],"=");
				sprintf(paramName,"%s",temp);
				//printf("Name=%s,",temp);
				temp=strtok(NULL,"=");
				sprintf(paramValue,"%s",temp);
				//printf("Value=%s\n",temp);
				
				
				if(strcasecmp(paramName,"omcSysNo") == 0)
				{
					*sysNo=atoi(paramValue);
				}	
			}
		}	
		close(fi);
		fclose(fp);
	}	
	else
	{
		exitLog("smeg:getOmcSysNo, Can not find omcd.conf");
		exit(1);
	}	
	return 1;
}

// void smeg_debug_log(const char *fmt,...)
// {
// // #if SMEG_DEBUG == 1
// #if 1
// 	char logFile[64];
// 	FILE *fp;
// 	time_t l_time;
// 	va_list ap;
// 	char buf[8192];
// 	struct tm *t;
// 	char timestr[64];
	
// 	l_time=time(NULL);
// 	t=localtime(&l_time);
// 	sprintf(logFile,"../log/smeg_%04d%02d%02d.log",t->tm_year+1900,t->tm_mon+1,t->tm_mday);
// 	fp=fopen(logFile,"a");
// 	if(fp!=NULL)
// 	{
// 		va_start(ap,fmt);
// 		vsprintf(buf,fmt,ap);
// 		sprintf(timestr,"%02d:%02d:%02d: ",t->tm_hour,t->tm_min,t->tm_sec);
// 		fputs(timestr,fp);
// 		fputs(buf,fp);
// 		fputs("\n",fp);
// 		fflush(fp);
// 		va_end(ap);
// 		fclose(fp);
// 	}
// #endif
// }
