/*************************************************
File name:	decodeASN.c	
Author: 		JianHui Zheng
Version:		9:00:00 
Date:  			2007-11-09
Description:This file defines the decode function when receive NRTRDE files 
						from remote VPMNs,then it generate the NRTRDE Error reports if
						the NRTRDE files contain error.At last it transform the NRTRDE
						files to the local CSV format.
			
			
			
												
History:               
No. 		
Author:		  
Date:		 
Version:	   
Description:
*************************************************/

#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "nrtrde.h"

/******************************************************/
/******           Function Declaration           ******/
/******************************************************/
/*******   From nrtrde.c   ********/
extern void printfInColor(char* message,int color);
extern void printfHPMNServer(HpmnServer* server);
extern void logMessage(char* message);
//extern void getSequenceNumber(char* squenceNumber,int type);
extern int getTagByName(char* name);
extern int addNDNode(char* tadig,char* fileName);

/*******   From decodeASN.c ********/
int parseAsnFile(char* fileName);
void makeNEFile(void);
int reportDBToLink(void);
int addNENode(char* senderTadig,char* fileName,int type,int recordNumber,char* errorCode);
int addNENodeInDB(char* senderTadig,char* fileName,int type,int recordNumber,char* errorCode);
int isCodeInASN(char* fileName,char* senderTadig);
int noUnknownTags(char* fileName,char* senderTadig);
int noRepeatTags(char* fileName,char* senderTadig);
int noConfuseInGrp(char* fileName,char* senderTadig);
int noIntOverLen(char* fileName,char* senderTadig);
int checkTagMissInGrp(char* fileName,char* senderTadig);
int isValidInGroup(int tag,int type);
void checkGrp(int* groupFlag,int groupType,int recordNumber,char* fileName,char* senderTadig);
int checkTagDetail(char* fileName,char* senderTadig);
void checkTag(int groupType,int recordNumber,char* fileName,char* senderTadig,int tag,int len,unsigned char* value);

int createLocCSV(char* fileName);
void writeField(int tag,int len,unsigned char* value,CallEvent* callEvent);
void writeCallEvent(char* fileName,CallEvent* callEvent);
void printCallEvent(CallEvent* callEvent);
void decodeASCII(int len,unsigned char* value,char* result);
void decodeInteger(int len,unsigned char* value,long* result);
void decodeBCD(int len,unsigned char* value,char* result);

/******************************************************/
/******           Variable Declaration           ******/
/******************************************************/
/*******   From nrtrde.c   ********/
/* The tag configuration */
extern TagNode tags[50];
/* The OMC_PUB database connection */
extern MYSQL* g_omcPubConn;
/* The CDR_DB database connection */
extern MYSQL* g_cdrConn;
/* The local UTC timeOffset */
extern char g_local_utc[8];
/* The tadig of local server */
extern char LOCAL_TADIG[8];
/* The source directory to send the file */
extern char SEND_DIR[256];
/* The directory to receive the file */
extern char RECV_DIR[256];
/* The backup directory */
extern char NR_RECV_BAK_DIR[256];
extern char NR_SEND_BAK_DIR[256];
extern char ND_RECV_BAK_DIR[256];
extern char ND_SEND_BAK_DIR[256];
extern char NE_RECV_BAK_DIR[256];
extern char NE_SEND_BAK_DIR[256];
extern char LOCAL_CSV_DIR[256];
/* The version of the NRTRDE Delivery report */
extern char ND_VERSION[8];
/* The version of the NRTRDE Error report */
extern char NE_VERSION[8];
/* The specificationVersionNumber of the NRTRDE file */
extern int NR_SVN;
/* The ReleaseVersionNumber of the NRTRDE file */
extern int NR_RVN;

/* The local MCC */
extern char g_local_mcc[6];
/* The local MNC */
extern char g_local_mnc[6];
/* The max value of the CallEventDuration */
extern int g_maxCallDuration;
/* The total count of hpmn servers in the hpmnConf table */
extern int g_hpmn_server_count;
/* The hpmn servers array, now suport 100 servers */
extern HpmnServer servers[HPMN_SERVER_COUNT];

/*******   From decodeASN.c   ********/
/* Use to create NRTRDE Error report */
NERepNode* pNEHead=NULL;
NERepNode* pNETail=NULL;

/*******   From seq_num_mng.c  *******/
extern int add_seq_obj(seq_buffer *seq_buf,seq_object *add_obj);
extern unsigned long find_seq_obj(seq_buffer *seq_buf,char *keyvalue);
extern int get_seq_num(char *tadig,int type,char *out_seq);
extern int init_seq();
extern int store_seq();

/*************************************************
Function:        // parseAsnFile
Description:     // Parse the NRTRDE File which coded in ASN Format
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:The name of NRTRDE File
Output:          // FAIL;SUCCESSFUL;
Return:          // 
Others:          // 
*************************************************/
int parseAsnFile(char *fileName)
{
	char senderTadig[8];
	char message[256];
	int i;

	
	sprintf(message,"Start to parse asn file=%s\n",fileName);
	logMessage(message);
	printfInColor(message,2);

	//get the sender tadig
	for(i=2;i<7;i++)
	{
		senderTadig[i-2]=(unsigned char)fileName[i];
	}
	senderTadig[i-2]='\0';
	
	
	if(isCodeInASN(fileName,senderTadig))
	{
		
		if(noUnknownTags(fileName,senderTadig))
		{

			if(noRepeatTags(fileName,senderTadig))
			{
				
				if(noConfuseInGrp(fileName,senderTadig))
				{
					
					if(noIntOverLen(fileName,senderTadig))
					{
						checkTagMissInGrp(fileName,senderTadig);
						checkTagDetail(fileName,senderTadig);
						createLocCSV(fileName);
					}	
					else
					{
						return FAIL;
					}	
					
				}	
				else
				{
					return FAIL;
				}	
				
			}	
			else
			{
				return FAIL;
			}	
			
		}
		
		else
		{
			return FAIL;
		}		
		
	}
	else
	{
		return FAIL;	
	}	
	
	return SUCCESSFUL;
}


/*************************************************
Function:        // addNENode
Description:     // Add the NRTRDE error report node to the link
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // senderTadig:the tadig of this record;
										fileName:the file name of the record;
										type:1-NRTRDE, 2-MOC, 3-MTC;
										recordNumber:the number of the record in the NRTRDE file
										errorCode:the error code of the record
Output:          // 
Return:          // 
Others:          // This function change value 'pNEHead' and 'pNETail'
*************************************************/
int addNENode(char* senderTadig,char* fileName,int type,int recordNumber,char* errorCode)
{
	NERepNode* node;
	
	node=(NERepNode*)malloc(sizeof(NERepNode));
	if(node)
	{
		sprintf(node->tadig,senderTadig);
		sprintf(node->fileName,fileName);
		node->type=type;
		node->recordNumber=recordNumber;
		sprintf(node->errorCode,errorCode);

		node->next=NULL;
		
		if(pNEHead == NULL || pNETail == NULL)
		{
			pNEHead=pNETail=node;
		}	
		else
		{
			pNETail->next=node;
			pNETail=node;
		}	
		return SUCCESSFUL;
	}
	else
	{
		return FAIL;
	}
}

/*************************************************
Function:        // addNENodeInDB
Description:     // Add the NRTRDE error report node in the CDR_DB.reportNRInfo
Calls:           // 
Called By:       // 
Table Accessed:  // CDR_DB.reportNRInfo
Table Updated:   // CDR_DB.reportNRInfo
Input:           // senderTadig:the tadig of this record;
										fileName:the file name of the record;
										type:1-NRTRDE, 2-MOC, 3-MTC;
										recordNumber:the number of the record in the NRTRDE file
										errorCode:the error code of the record
Output:          // 
Return:          // 
Others:          // 
*************************************************/
int addNENodeInDB(char* senderTadig,char* fileName,int type,int recordNumber,char* errorCode)
{
	char sqlstr[512];
	
	//printf("tadig=%s,fileName=%s,type=%d,recordNumber=%d,errorCode=%s\n",senderTadig,fileName,type,recordNumber,errorCode);
	
	sprintf(sqlstr,"INSERT INTO reportNRInfo (tadig, fileName, type, errorType, recordNumber, errorCode) VALUES ('%s', '%s', '%d', '%d', '%d', '%s')",
					senderTadig,fileName,2,type,recordNumber,errorCode);
	mysql_getnores(g_cdrConn,sqlstr);
	
	
	return SUCCESSFUL;
}

/*************************************************
Function:        // reportDBToLink
Description:     // Get the report info from CDR_DB.reportNRInfo to link
Calls:           // addNENode
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // 
*************************************************/
int reportDBToLink(void)
{
	MYSQL_RES *res;
	MYSQL_ROW row;
	char sqlstr[512];
	char message[512];
	
	
	sprintf(sqlstr,"SELECT tadig,fileName,type,errorType,recordNumber,errorCode FROM CDR_DB.reportNRInfo ");
							
	res=mysql_getres(g_cdrConn,sqlstr);
	if(res == NULL)
	{
		sprintf(message,"[ERR %d][reportDBToLink]:%s\n",mysql_errno(g_cdrConn),sqlstr);
		logMessage(message);
		return FAIL;
	}		
	
	while((row = mysql_fetch_row(res)) != NULL)
	{
		//type-1:ND 2:NE
		//ND
		if(atoi(row[2])==1)
		{
			addNDNode(row[0],row[1]);
		}
		//NE
		else
		{
			addNENode(row[0],row[1],atoi(row[3]),atoi(row[4]),row[5]);
		}		
	}
	
	sprintf(sqlstr,"DELETE FROM reportNRInfo");
	mysql_getnores(g_cdrConn,sqlstr);	
	
	mysql_free_result(res);
	return SUCCESSFUL;
}

/*************************************************
Function:        // makeNEFile
Description:     // Make the error report for sending to VPMNs, then free the link of error report
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // The error reports
Return:          // 
Others:          // This function will change the value 'pNEHead' and 'pNETail'
*************************************************/
void makeNEFile()
{
	struct tm *now;
	char createTime[32];
	char startTime[32];
	char endTime[32];
	char fileName[512];
	char squenceNumber[8];
	char command[512];
	char message[256];
	time_t t;
	NERepNode* tmpNode,*tmpN;
	int recordCount;												//The record count of NE file
	int i;
	
	reportDBToLink();
	
	t=time(NULL);
	now=localtime(&t);

	//get the create time
	sprintf(createTime,"%04d%02d%02d%02d%02d%02d%s",
	      		now->tm_year+1900,
	      		now->tm_mon+1,
	      		now->tm_mday,
	      		now->tm_hour,
	      		now->tm_min,
	      		now->tm_sec,
	      		g_local_utc);
	      		
	//get the start time       		
	sprintf(endTime,"%04d%02d%02d%02d%02d%02d%s",
	      		now->tm_year+1900,
	      		now->tm_mon+1,
	      		now->tm_mday,
	      		now->tm_hour,
	      		now->tm_min,
	      		now->tm_sec,
	      		g_local_utc);      	 
	      		     		
	//get the start time    
	t=time(NULL)-24*60*60;
	now=localtime(&t);       		
	sprintf(startTime,"%04d%02d%02d%02d%02d%02d%s",
	      		now->tm_year+1900,
	      		now->tm_mon+1,
	      		now->tm_mday,
	      		now->tm_hour,
	      		now->tm_min,
	      		now->tm_sec,
	      		g_local_utc);  
	      		
	      		      		
	        		
	      		
	for(i=0;i<g_hpmn_server_count;i++)
	{
		//get the record count of this HPMN server
		recordCount=0;
		tmpNode=pNEHead;
		while(tmpNode)
		{
			if(strcmp(servers[i].tadig,tmpNode->tadig) == 0)
			{
				recordCount++;
			}			
			tmpNode=tmpNode->next;
		}
		
		if(recordCount > 0)
		{
			//write the head of the error report
			//getSequenceNumber(squenceNumber,2);
			get_seq_num(servers[i].tadig,2,squenceNumber);
			sprintf(fileName,"%sNE%s%s%s",SEND_DIR,LOCAL_TADIG,servers[i].tadig,squenceNumber);
			sprintf(command,"echo 'NE,%s,%s,%s,%s,%s,%s,%s'>>%s",
							NE_VERSION,
							LOCAL_TADIG,
							servers[i].tadig,
							squenceNumber,
							createTime,startTime,endTime,
							fileName);
			system(command);				
			
			sprintf(message,"Make Error report %s\n",fileName);
			logMessage(message);
			
			
			//write the content of the error report
			tmpNode=pNEHead;
			while(tmpNode)
			{
				if(strcmp(servers[i].tadig,tmpNode->tadig) == 0)
				{
					//NRTRDE file error
					if(tmpNode->type == 1)
					{
						sprintf(command,"echo '%s,,,%s'>>%s",tmpNode->fileName,tmpNode->errorCode,fileName);
						system(command);
					}	
					//MOC error
					else if(tmpNode->type == 2)
					{
						sprintf(command,"echo '%s,%d,MOC,%s'>>%s",tmpNode->fileName,tmpNode->recordNumber,tmpNode->errorCode,fileName);
						system(command);
					}	
					//MTC error
					else if(tmpNode->type == 3)
					{
						sprintf(command,"echo '%s,%d,MTC,%s'>>%s",tmpNode->fileName,tmpNode->recordNumber,tmpNode->errorCode,fileName);
						system(command);
					}	
					//GPRS error
					else if(tmpNode->type == 4)
					{
						sprintf(command,"echo '%s,%d,GPRS,%s'>>%s",tmpNode->fileName,tmpNode->recordNumber,tmpNode->errorCode,fileName);
						system(command);
					}	
					
				}
				tmpNode=tmpNode->next;
			}
			
			//write the tail of the error report
			sprintf(command,"echo 'END,%d'>>%s",recordCount+2,fileName);
			system(command);
		}	
	}
	
	//free the link	  	
	tmpNode=pNEHead;
	while(tmpNode)
	{
		tmpN=tmpNode->next;
		free(tmpNode);
		tmpNode=tmpN;
	}
	pNEHead=NULL;
	pNETail=NULL;      		
}

/*************************************************
Function:        // isCodeInASN
Description:     // Judge the NRTRDE files received whether is coded in ASN.1
Calls:           // addNENodeInDB;
Called By:       // parseAsnFile;
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file to parse; senderTadig:who send the NRTRDE file
Output:          // 
Return:          // 0:not code in ASN; 1:code in ASN;
Others:          // If the tag or the length of the Nrtrde is incorrect, then it not coded in ASN.1 
*************************************************/
int isCodeInASN(char* fileName,char* senderTadig)
{
	FILE* fp;
	int fi;
	unsigned char buf[256];
	int readBytes;
	int lLen=0;
	long vLenParse=0;
	long vLenRead=0;
	int i;
	int result;
	char message[256];	
	char fullFileName[512];
	
	sprintf(fullFileName,"%s%s",RECV_DIR,fileName);
	//printf("fullFileName=%s\n",fullFileName);

	//Open and read the NRTRDE file

	fp=fopen(fullFileName,"r");

	if(fp == NULL)
	{
		printf("error=%s\n",strerror(errno));	
		return 0;
	}
	//get the file no of this file
	fi=fileno(fp);

	if((readBytes=read(fi,buf,1))==1)
	{
		//get the nrtrde tag=1
		if(buf[0] == 0x61)
		{
			//get the nrtrde length
			if((readBytes=read(fi,buf,1))==1)
			{
				//The length have more than one byte
				if((buf[0] & 0x80) == 0x80)
				{
					lLen=buf[0] & 0x7F;
					if((readBytes=read(fi,buf,lLen))==lLen)
					{	
						vLenParse=0;
						for(i=0;i<lLen;i++)
						{
							vLenParse=vLenParse*256+buf[i];
						}
						
						vLenRead=0;
						while((readBytes=read(fi,buf,1))==1)
						{
							vLenRead+=readBytes;
						}
						//printf("parse length=%ld\n",vLenParse);
						//printf("read length=%ld\n",vLenRead);
						if(vLenParse == vLenRead)	
						{
							result=1;
						}	
						else
						{
							result=0;
							addNENodeInDB(senderTadig,fileName,1,0,"53");
						}	
					}
					else
					{
						result=0;
						addNENodeInDB(senderTadig,fileName,1,0,"53");
					}		
				}
				//the length have only one byte
				else
				{
					vLenParse=buf[0] & 0x7F;
					
					vLenRead=0;
					while((readBytes=read(fi,buf,1))==1)
					{
						vLenRead+=readBytes;
					}
					
					if(vLenParse == vLenRead)
					{
						result=1;
					}
					else
					{
						result=0;
						addNENodeInDB(senderTadig,fileName,1,0,"53");
					}	
				}		
			}	
			else
			{
				result=0;
				addNENodeInDB(senderTadig,fileName,1,0,"53");
			}	
		}	
		else
		{
			result=0;
			addNENodeInDB(senderTadig,fileName,1,0,"53");
		}	
	}	
	else
	{
		result=0;
		addNENodeInDB(senderTadig,fileName,1,0,"53");
	}	
	
	if(result==0)
	{
		sprintf(message,"The file=%s is not coded in ASN.1,Error Code(53)\n",fileName);
		logMessage(message);
		printfInColor(message,1);
	}	
	close(fi);
	fclose(fp);
	
	return result;
}

/*************************************************
Function:        // noUnknownTags
Description:     // Judge the NRTRDE file whether contains the unknown tags
Calls:           // 
Called By:       // parseAsnFile;
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file to parse; senderTadig:who send the NRTRDE file
Output:          // 
Return:          // 1:not contain unknown tags; 0:contain unknown tags;
Others:          // For example there is tag=51 in the NRTRDE file
*************************************************/
int noUnknownTags(char* fileName,char* senderTadig)
{
	FILE* fp;
	int fi;
	unsigned char buf[256];
	int readBytes;
	char message[256];
	int tag;
	long lLen;
	long vLen;
	long callEvePos;
	long callEveEndPos;
	long callEveLength;
	int isStruct;
	int recordNumber;
	int groupType;
	int haveCallEvent;
	int i;
	char fullFileName[512];
	
	
	
	sprintf(fullFileName,"%s%s",RECV_DIR,fileName);
	
	//Open and read the NRTRDE file
	fp=fopen(fullFileName,"r");

	if(fp == NULL)
		return 0;
		
	//get the file no of this file
	fi=fileno(fp);
	
	//read the NRTRDE header
	haveCallEvent=0;
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		if(tag >= 50 || tags[tag].tagValue == 0)
		{
			addNENodeInDB(senderTadig,fileName,1,0,"50");
			sprintf(message,"The file=%s contains unknown tag=%d,Error Code(50)\n",fileName,tag);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
	
			return 0;
		}
		
		
		//get the position of the CallEventList
		if(tag == getTagByName("CallEventList"))
		{
			callEvePos=ftell(fp)-1;
			haveCallEvent=1;
			//printf("callEvePos=%ld\n",callEvePos);
		}	
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
					if(tag == getTagByName("CallEventList"))
					{
						callEveEndPos=callEvePos+vLen+lLen+2;		
						callEveLength=vLen;
						break;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
				}
				if(tag == getTagByName("CallEventList"))
				{
					callEveEndPos=callEvePos+vLen+lLen+1;		
					callEveLength=vLen;
					break;
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}	
	
	//read the NRTRDE CallEventList
	if(!haveCallEvent)
	{
		//Judge this tag wether is CallEventList
		sprintf(message,"The file=%s miss tag=2(CallEventList)\n",fileName);
		logMessage(message);
		printfInColor(message,1);
		close(fi);
		fclose(fp);
		return 0;
	}	
	lseek(fi,callEvePos,SEEK_SET);
	recordNumber=0;

	while((readBytes=read(fi,buf,1))==1)
	{
		callEveLength-=readBytes;
		
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				callEveLength-=readBytes;
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		
		//printf("tag=%d\n",tag);
		if(tag == getTagByName("Moc"))
		{
			recordNumber++;
			groupType=2;
		}	
		else if(tag == getTagByName("Mtc"))
		{
			recordNumber++;
			groupType=3;
		}	
		else if(tag == getTagByName("Gprs"))
		{
			recordNumber++;
			groupType=4;
		}	
			
		if(tag >= 50 || tags[tag].tagValue == 0)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"50");
			sprintf(message,"The file=%s contains unknown tag=%d,recordNumber=%d,Error Code(50)\n",fileName,tag,recordNumber);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}
		
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			callEveLength-=readBytes;

			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					callEveLength-=readBytes;
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
						callEveLength-=readBytes;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;

				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
					callEveLength-=readBytes;
				}
				
			}
			//The CallEventList is finish
			if(callEveLength<0)
			{	
				break;
			}	
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}
	
	//read the NRTRDE tail
	lseek(fi,callEveEndPos,SEEK_SET);
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		if(tag >= 50 || tags[tag].tagValue == 0)
		{
			addNENodeInDB(senderTadig,fileName,1,0,"50");
			sprintf(message,"The file=%s contains unknown tag=%d,Error Code(50)\n",fileName,tag);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}
	close(fi);
	fclose(fp);
	
	return 1;
}

/*************************************************
Function:        // noRepeatTags
Description:     // Judge the NRTRDE file wether have the repeat tags in group
Calls:           // 
Called By:       // parseAsnFile;
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file to parse; senderTadig:who send the NRTRDE file
Output:          // 
Return:          // 1:no repeat tags in group; 0:repeat tags in group;
Others:          // For example there are two CallEventsCount tag in the NRTRDE group
*************************************************/
int noRepeatTags(char* fileName,char* senderTadig)
{
	FILE* fp;
	int fi;
	unsigned char buf[256];
	int readBytes;
	char message[256];
	int tag;
	long lLen;
	long vLen;
	long callEvePos;
	long callEveEndPos;
	long callEveLength;
	int headGrpTagFlag[50];
	int cdrGrpTagFlag[50];
	int isStruct;
	int recordNumber;
	int groupType;
	int i;
	char fullFileName[512];
	
	
	
	sprintf(fullFileName,"%s%s",RECV_DIR,fileName);
	//initial
	memset(headGrpTagFlag,0,sizeof(int)*50);
	memset(cdrGrpTagFlag,0,sizeof(int)*50);
	
	//Open and read the NRTRDE file
	fp=fopen(fullFileName,"r");

	if(fp == NULL)
		return 0;
		
	//get the file no of this file
	fi=fileno(fp);
	
	//read the NRTRDE header
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		//get the position of the CallEventList
		if(tag == getTagByName("CallEventList"))
		{
			callEvePos=ftell(fp)-1;
			//printf("callEvePos=%ld\n",callEvePos);
		}	
		
		//Judge whether the tag repeat in group
		if(headGrpTagFlag[tag] == 0)
		{	
			headGrpTagFlag[tag]=1;
		}
		else if(headGrpTagFlag[tag] == 1)
		{
			addNENodeInDB(senderTadig,fileName,1,0,"51");
			sprintf(message,"The file=%s have repeat tag=%d(%s) in NRTRDE Group(head),Error Code(51)\n",fileName,tag,tags[tag].fieldName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}	
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
					if(tag == getTagByName("CallEventList"))
					{
						callEveEndPos=callEvePos+vLen+lLen+2;		
						callEveLength=vLen;
						break;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
				}
				if(tag == getTagByName("CallEventList"))
				{
					callEveEndPos=callEvePos+vLen+lLen+1;		
					callEveLength=vLen;
					break;
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}	
	
	//read the NRTRDE CallEventList
	recordNumber=0;
	lseek(fi,callEvePos,SEEK_SET);
	while((readBytes=read(fi,buf,1))==1)
	{
		callEveLength-=readBytes;
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				callEveLength-=readBytes;
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		if(tag == getTagByName("Moc"))
		{
			recordNumber++;
			groupType=2;
			memset(cdrGrpTagFlag,0,sizeof(int)*50);
		}	
		else if(tag == getTagByName("Mtc"))
		{
			recordNumber++;
			groupType=3;
			memset(cdrGrpTagFlag,0,sizeof(int)*50);
		}
		else if(tag == getTagByName("Gprs"))
		{
			recordNumber++;
			groupType=4;
			memset(cdrGrpTagFlag,0,sizeof(int)*50);
		}	
		
		//Judge whether the tag repeat in group
		if(cdrGrpTagFlag[tag] == 0)
		{	
			cdrGrpTagFlag[tag]=1;
		}
		else if(cdrGrpTagFlag[tag] == 1)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"51");
			if(groupType == 2)
				sprintf(message,"The file=%s have repeat tag=%d(%s) in MOC Group,recordNumber=%d,Error Code(51)\n",fileName,tag,tags[tag].fieldName,recordNumber);
			else if(groupType == 3)
				sprintf(message,"The file=%s have repeat tag=%d(%s) in MTC Group,recordNumber=%d,Error Code(51)\n",fileName,tag,tags[tag].fieldName,recordNumber);
			else if(groupType == 4)
				sprintf(message,"The file=%s have repeat tag=%d(%s) in GPRS Group,recordNumber=%d,Error Code(51)\n",fileName,tag,tags[tag].fieldName,recordNumber);
			
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}	
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			callEveLength-=readBytes;
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					callEveLength-=readBytes;
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
						callEveLength-=readBytes;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
					callEveLength-=readBytes;
				}
				
			}
			//The CallEventList is finish
			if(callEveLength<0)
			{	
				break;
			}	
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}
	
	//read the NRTRDE tail
	lseek(fi,callEveEndPos,SEEK_SET);
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		
		//Judge whether the tag repeat in group
		if(headGrpTagFlag[tag] == 0)
		{	
			headGrpTagFlag[tag]=1;
		}
		else if(headGrpTagFlag[tag] == 1)
		{
			addNENodeInDB(senderTadig,fileName,1,0,"51");
			sprintf(message,"The file=%s have repeat tag=%d(%s) in NRTRDE Group(tail),Error Code(51)\n",fileName,tag,tags[tag].fieldName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}	
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}
	close(fi);
	fclose(fp);
	
	return 1;
}

/*************************************************
Function:        // noConfuseInGrp
Description:     // Judge wether there is a confuse tag in the group
Calls:           // isValidInGroup;
Called By:       // parseAsnFile;
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file to parse; senderTadig:who send the NRTRDE file
Output:          // 
Return:          // 1:no confuse; 0:confuse
Others:          // For example the ConnectedNumber tag appear in the MTC group
*************************************************/
int noConfuseInGrp(char* fileName,char* senderTadig)
{
	FILE* fp;
	int fi;
	unsigned char buf[256];
	int readBytes;
	char message[256];
	int tag;
	long lLen;
	long vLen;
	long callEvePos;
	long callEveEndPos;
	long callEveLength;
	int isStruct;
	int groupType;
	int recordNumber;
	int i;
	char fullFileName[512];
	
	
	
	sprintf(fullFileName,"%s%s",RECV_DIR,fileName);
	//Open and read the NRTRDE file
	fp=fopen(fullFileName,"r");

	if(fp == NULL)
		return 0;
		
	//get the file no of this file
	fi=fileno(fp);
	
	//read the NRTRDE header
	groupType=1;
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		//get the position of the CallEventList
		if(tag == getTagByName("CallEventList"))
		{
			callEvePos=ftell(fp)-1;
			//printf("callEvePos=%ld\n",callEvePos);
		}	
		
		//Judge whether the tag in the group is valid
		if(!isValidInGroup(tag,groupType))
		{
			addNENodeInDB(senderTadig,fileName,1,0,"52");
			sprintf(message,"The file=%s have a not expected tag=%d(%s) in the NRTRDE group(head),Error Code(52)\n",fileName,tag,tags[tag].fieldName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
					if(tag == getTagByName("CallEventList"))
					{
						callEveEndPos=callEvePos+vLen+lLen+2;		
						callEveLength=vLen;
						break;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
				}
				if(tag == getTagByName("CallEventList"))
				{
					callEveEndPos=callEvePos+vLen+lLen+1;		
					callEveLength=vLen;
					break;
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}	
	
	//read the NRTRDE CallEventList
	recordNumber=0;
	lseek(fi,callEvePos,SEEK_SET);
	while((readBytes=read(fi,buf,1))==1)
	{
		callEveLength-=readBytes;
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				callEveLength-=readBytes;
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		
		//change the cdr type
		if(tag == getTagByName("Moc"))
		{
			recordNumber++;
			groupType=2;
		}
		else if(tag == getTagByName("Mtc"))
		{
			recordNumber++;
			groupType=3;
		}	
		else if(tag == getTagByName("Gprs"))
		{
			recordNumber++;
			groupType=4;
		}	
		if(!isValidInGroup(tag,groupType))
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"52");
			if(groupType == 2)
				sprintf(message,"The file=%s have a not expected tag=%d(%s) in the MOC group,recordNumber=%d,Error Code(52)\n",fileName,tag,tags[tag].fieldName,recordNumber);
			else if(groupType == 3)
				sprintf(message,"The file=%s have a not expected tag=%d(%s) in the MTC group,recordNumber=%d,Error Code(52)\n",fileName,tag,tags[tag].fieldName,recordNumber);
			else if(groupType == 4)	
				sprintf(message,"The file=%s have a not expected tag=%d(%s) in the GPRS group,recordNumber=%d,Error Code(52)\n",fileName,tag,tags[tag].fieldName,recordNumber);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}	
			
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			callEveLength-=readBytes;
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					callEveLength-=readBytes;
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
						callEveLength-=readBytes;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
					callEveLength-=readBytes;
				}
				
			}
			//The CallEventList is finish
			if(callEveLength<0)
			{	
				break;
			}	
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}
	
	//read the NRTRDE tail
	groupType=1;
	lseek(fi,callEveEndPos,SEEK_SET);
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		if(!isValidInGroup(tag,groupType))
		{
			addNENodeInDB(senderTadig,fileName,1,0,"52");
			sprintf(message,"The file=%s have a not expected tag=%d(%s) in the NRTRDE group(tail),Error Code(52)\n",fileName,tag,tags[tag].fieldName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}
	
	close(fi);
	fclose(fp);
	
	return 1;
}

/*************************************************
Function:        // noIntOverLen
Description:     // Judge the Integer code tag's length whether over 4 or 8 bytes
Calls:           // 
Called By:       // parseAsnFile;
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file to parse; senderTadig:who send the NRTRDE file
Output:          // 
Return:          // 1:not over; 0:over;
Others:          // For example the CallReference tag's length is 9 bytes
*************************************************/
int noIntOverLen(char* fileName,char* senderTadig)
{
	FILE* fp;
	int fi;
	unsigned char buf[256];
	int readBytes;
	char message[256];
	int tag;
	long lLen;
	long vLen;
	long callEvePos;
	long callEveEndPos;
	long callEveLength;
	int isStruct;
	int groupType;
	int recordNumber;
	int i;
	char fullFileName[512];
	
	
	
	sprintf(fullFileName,"%s%s",RECV_DIR,fileName);
	
	//Open and read the NRTRDE file
	fp=fopen(fullFileName,"r");
	
	if(fp == NULL)
		return 0;
		
	//get the file no of this file
	fi=fileno(fp);
	
	//read the NRTRDE header
	groupType=1;
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		//get the position of the CallEventList
		if(tag == getTagByName("CallEventList"))
		{
			callEvePos=ftell(fp)-1;
			//printf("callEvePos=%ld\n",callEvePos);
		}	
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
					if(tag == getTagByName("CallEventList"))
					{
						callEveEndPos=callEvePos+vLen+lLen+2;		
						callEveLength=vLen;
						
						break;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
				}
				
				//Judge the Integer length whether over 4-8 bytes	
				if(!isStruct)
				{
					if(tags[tag].code == 1)
					{	
						//The tag length in head code in Integer is not more than 4 bytes
						//printf("head tag=%d,vLen=%d\n",tag,vLen);
						if(vLen > 4)
						{
							addNENodeInDB(senderTadig,fileName,groupType,0,"54");
							sprintf(message,"The file=%s have a Integer tag=%d(%s) in the NRTRDE group(head),length=%ld>4,Error Code(54)\n",fileName,tag,tags[tag].fieldName,vLen);
							logMessage(message);
							printfInColor(message,1);
							close(fi);
							fclose(fp);
							return 0;
						}	
					}	
				}
				
				if(tag == getTagByName("CallEventList"))
				{
					callEveEndPos=callEvePos+vLen+lLen+1;		
					callEveLength=vLen;
					
					
					break;
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}	
	
	//read the NRTRDE CallEventList
	recordNumber=0;
	lseek(fi,callEvePos,SEEK_SET);
	while((readBytes=read(fi,buf,1))==1)
	{
		callEveLength-=readBytes;
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				callEveLength-=readBytes;
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		
		//change the cdr type
		if(tag == getTagByName("Moc"))
		{
			recordNumber++;
			groupType=2;
		}
		else if(tag == getTagByName("Mtc"))
		{
			recordNumber++;
			groupType=3;
		}	
		else if(tag == getTagByName("Gprs"))
		{
			recordNumber++;
			groupType=4;
		}	
			
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			callEveLength-=readBytes;
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					callEveLength-=readBytes;
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
						callEveLength-=readBytes;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
					callEveLength-=readBytes;
				}
				
			}
			
			//Judge the Integer length whether over 4-8 bytes
			if(!isStruct)
			{
				if(tags[tag].code == 1)
				{	
					//printf("cdr tag=%d,vLen=%d\n",tag,vLen);
					//The tag length in tail code in Integer is not more than 8 bytes
					if(tag == getTagByName("DataVolumeIncoming") ||
						 tag == getTagByName("DataVolumeOutgoing") ||
						 tag == getTagByName("CallReference") ||
						 tag == getTagByName("ChargingId"))
					{
						if(vLen > 8)
						{
							addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"55");
							if(groupType == 2)
								sprintf(message,"The file=%s have a Integer tag=%d(%s) in the MOC group,length=%ld>8,recordNumber=%d,Error Code(55)\n",fileName,tag,tags[tag].fieldName,vLen,recordNumber);
							else if(groupType == 3)
								sprintf(message,"The file=%s have a Integer tag=%d(%s) in the MTC group,length=%ld>8,recordNumber=%d,Error Code(55)\n",fileName,tag,tags[tag].fieldName,vLen,recordNumber);
							else if(groupType == 4)
								sprintf(message,"The file=%s have a Integer tag=%d(%s) in the GPRS group,length=%ld>8,recordNumber=%d,Error Code(55)\n",fileName,tag,tags[tag].fieldName,vLen,recordNumber);	
							logMessage(message);
							printfInColor(message,1);
							close(fi);
							fclose(fp);
							return 0;
						}	
					}
					//The tag length in tail code in Integer is not more than 4 bytes
					else
					{
						if(vLen > 4)
						{
							addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"54");
							if(groupType == 2)
								sprintf(message,"The file=%s have a Integer tag=%d(%s) in the MOC group,length=%ld>4,recordNumber=%d,Error Code(54)\n",fileName,tag,tags[tag].fieldName,vLen,recordNumber);
							else if(groupType == 3)
								sprintf(message,"The file=%s have a Integer tag=%d(%s) in the MTC group,length=%ld>4,recordNumber=%d,Error Code(54)\n",fileName,tag,tags[tag].fieldName,vLen,recordNumber);
							else if(groupType == 4)
								sprintf(message,"The file=%s have a Integer tag=%d(%s) in the GPRS group,length=%ld>4,recordNumber=%d,Error Code(54)\n",fileName,tag,tags[tag].fieldName,vLen,recordNumber);	
							logMessage(message);
							printfInColor(message,1);
							close(fi);
							fclose(fp);
							return 0;
						}	
					}		 
				}
						
			}	
			
			//The CallEventList is finish
			if(callEveLength<0)
			{	
				break;
			}	
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}
	
	//read the NRTRDE tail
	groupType=1;
	lseek(fi,callEveEndPos,SEEK_SET);
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
				}
				//Judge the Integer length whether over 4-8 bytes
				if(!isStruct)
				{
					if(tags[tag].code == 1)
					{
						//The tag length in tail code in Integer is not more than 4 bytes
						//printf("head tag=%d,vLen=%d\n",tag,vLen);
						if(vLen > 4)
						{
							addNENodeInDB(senderTadig,fileName,groupType,0,"54");
							sprintf(message,"The file=%s have a Integer tag=%d(%s) in the NRTRDE group(tail),length=%ld>4,Error Code(54)\n",fileName,tag,tags[tag].fieldName,vLen);
							logMessage(message);
							printfInColor(message,1);
							close(fi);
							fclose(fp);
							return 0;
						}		
					}
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}
	close(fi);
	fclose(fp);
	
	return 1;
}

/*************************************************
Function:        // checkTagMissInGrp
Description:     // Check whether there are some Mandatory tag missing in the group
Calls:           // checkGrp;
Called By:       // parseAsnFile;
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file to parse; senderTadig:who send the NRTRDE file
Output:          // 
Return:          // 
Others:          // For example the Imsi miss in the MOC group
*************************************************/
int checkTagMissInGrp(char* fileName,char* senderTadig)
{
	FILE* fp;
	int fi;
	unsigned char buf[256];
	int readBytes;
	char message[256];
	int tag;
	long lLen;
	long vLen;
	long callEvePos;
	long callEveEndPos;
	long callEveLength;
	int headGrpTagFlag[50];
	int cdrGrpTagFlag[50];
	int isStruct;
	int recordNumber;
	int groupType;
	int i;	
	char fullFileName[512];
	
	
	
	sprintf(fullFileName,"%s%s",RECV_DIR,fileName);
	
	
	//initial
	memset(headGrpTagFlag,0,sizeof(int)*50);
	memset(cdrGrpTagFlag,0,sizeof(int)*50);
	
	//Open and read the NRTRDE file

	fp=fopen(fullFileName,"r");

	if(fp == NULL)
		return 0;
		
	//get the file no of this file
	fi=fileno(fp);
	
	//read the NRTRDE header
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		//get the position of the CallEventList
		if(tag == getTagByName("CallEventList"))
		{
			callEvePos=ftell(fp)-1;
			//printf("callEvePos=%ld\n",callEvePos);
		}	
		
		//fill the headGrpTagFlag
		headGrpTagFlag[tag]=1;
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
					if(tag == getTagByName("CallEventList"))
					{
						callEveEndPos=callEvePos+vLen+lLen+2;		
						callEveLength=vLen;
						break;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
				}
				if(tag == getTagByName("CallEventList"))
				{
					callEveEndPos=callEvePos+vLen+lLen+1;		
					callEveLength=vLen;
					break;
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}	
	
	//read the NRTRDE CallEventList
	recordNumber=0;
	lseek(fi,callEvePos,SEEK_SET);
	while((readBytes=read(fi,buf,1))==1)
	{
		callEveLength-=readBytes;
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				callEveLength-=readBytes;
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		if(tag == getTagByName("Moc"))
		{
			if(recordNumber > 0)
			{
				checkGrp(cdrGrpTagFlag,groupType,recordNumber,fileName,senderTadig);
			}
			recordNumber++;
			groupType=2;
			memset(cdrGrpTagFlag,0,sizeof(int)*50);
		}	
		else if(tag == getTagByName("Mtc"))
		{
			if(recordNumber > 0)
			{
				checkGrp(cdrGrpTagFlag,groupType,recordNumber,fileName,senderTadig);
			}
			recordNumber++;
			groupType=3;
			memset(cdrGrpTagFlag,0,sizeof(int)*50);
		}
		else if(tag == getTagByName("Gprs"))
		{
			if(recordNumber > 0)
			{
				checkGrp(cdrGrpTagFlag,groupType,recordNumber,fileName,senderTadig);
			}
			recordNumber++;
			groupType=4;
			memset(cdrGrpTagFlag,0,sizeof(int)*50);
		}	
		
		//Fill the cdrGrpTagFlag
		cdrGrpTagFlag[tag]=1;	
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			callEveLength-=readBytes;
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					callEveLength-=readBytes;
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
						callEveLength-=readBytes;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
					callEveLength-=readBytes;
				}
				
			}
			//The CallEventList is finish
			if(callEveLength<0)
			{	
				break;
			}	
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}
	
	//check the last cdr record
	if(recordNumber > 0)
	{
		checkGrp(cdrGrpTagFlag,groupType,recordNumber,fileName,senderTadig);
	}
	
	//read the NRTRDE tail
	groupType=1;
	lseek(fi,callEveEndPos,SEEK_SET);
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return 0;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		
		//Fill the headGrpTagFlag
		headGrpTagFlag[tag]=1;

		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return 0;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return 0;
		}		
	}
	//check the NRTRDE head and tail
	checkGrp(headGrpTagFlag,groupType,0,fileName,senderTadig);
	
	close(fi);
	fclose(fp);
	
	return 1;
}

/*************************************************
Function:        // checkTagDetail
Description:     // Get the value of the every tag
Calls:           // checkTag;
Called By:       // parseAsnFile;
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file to parse; senderTadig:who send the NRTRDE file
Output:          // 
Return:          // SUCCESSFUL; FAIL;
Others:          // 
*************************************************/
int checkTagDetail(char* fileName,char* senderTadig)
{
	FILE* fp;
	int fi;
	unsigned char buf[256];
	int readBytes;
	char message[256];
	int tag;
	long lLen;
	long vLen;
	long callEvePos;
	long callEveEndPos;
	long callEveLength;
	int isStruct;
	int recordNumber;
	int recordNumberP;
	int groupType;
	int i;	
	char fullFileName[512];
	
	
	
	sprintf(fullFileName,"%s%s",RECV_DIR,fileName);
	
	//Open and read the NRTRDE file

	fp=fopen(fullFileName,"r");

	if(fp == NULL)
		return FAIL;
		
	//get the file no of this file
	fi=fileno(fp);
	
	//read the NRTRDE header
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return FAIL;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		//get the position of the CallEventList
		if(tag == getTagByName("CallEventList"))
		{
			callEvePos=ftell(fp)-1;
			//printf("callEvePos=%ld\n",callEvePos);
		}	
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
					if(tag == getTagByName("CallEventList"))
					{
						callEveEndPos=callEvePos+vLen+lLen+2;		
						callEveLength=vLen;
						break;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return FAIL;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
					if(readBytes == vLen)
					{	
						//parse the value of the tag
						checkTag(1,0,fileName,senderTadig,tag,vLen,buf);
						
						//get the recordNumber by parse
						if(tag == getTagByName("CallEventsCount"))
						{
							recordNumberP=0;
							for(i=0;i<vLen;i++)
							{
								recordNumberP=recordNumberP*256+buf[i];
							}
						}	
					}	
				}
				if(tag == getTagByName("CallEventList"))
				{
					callEveEndPos=callEvePos+vLen+lLen+1;		
					callEveLength=vLen;
					break;
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return FAIL;
		}		
	}	
	
	//read the NRTRDE CallEventList
	recordNumber=0;
	lseek(fi,callEvePos,SEEK_SET);
	while((readBytes=read(fi,buf,1))==1)
	{
		callEveLength-=readBytes;
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				callEveLength-=readBytes;
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return FAIL;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		if(tag == getTagByName("Moc"))
		{
			recordNumber++;
			groupType=2;
		}	
		else if(tag == getTagByName("Mtc"))
		{
			recordNumber++;
			groupType=3;
		}
		else if(tag == getTagByName("Gprs"))
		{
			recordNumber++;
			groupType=4;
		}	
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			callEveLength-=readBytes;
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					callEveLength-=readBytes;
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
						callEveLength-=readBytes;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return FAIL;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
					callEveLength-=readBytes;
					//Parse the value of the tag
					checkTag(groupType,recordNumber,fileName,senderTadig,tag,vLen,buf);
				}
				
			}
			//The CallEventList is finish
			if(callEveLength<0)
			{	
				break;
			}	
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return FAIL;
		}		
	}
	
	//read the NRTRDE tail
	groupType=1;
	lseek(fi,callEveEndPos,SEEK_SET);
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return FAIL;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);

		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return FAIL;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
					//Parse the value of the tag
					checkTag(1,0,fileName,senderTadig,tag,vLen,buf);
					//get the recordNumber by parse
					if(tag == getTagByName("CallEventsCount"))
					{
						recordNumberP=0;
						for(i=0;i<vLen;i++)
						{
							recordNumberP=recordNumberP*256+buf[i];
						}
					}	
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return FAIL;
		}		
	}
	
	//CallEventsCount not match the recordNumber, Error Code 400
	if(recordNumberP != recordNumber)
	{
		addNENodeInDB(senderTadig,fileName,1,0,"400");
		sprintf(message,"The file=%s tag=20(CallEventsCount) does match the count of Call Events in the NRTRDE group,Error Code(400)\n",fileName);
		logMessage(message);
		printfInColor(message,1);
	}	

	close(fi);
	fclose(fp);
	
	return SUCCESSFUL;
}

/*************************************************
Function:        // createLocCSV
Description:     // Transform the NRTRDE to local csv format
Calls:           // writeField;
Called By:       // parseAsnFile;
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file name of the NRTRDE file
Output:          // 
Return:          // SUCCESSFUL; FAIL;
Others:          // 
*************************************************/
int createLocCSV(char* fileName)
{
	FILE* fp;
	int fi;
	unsigned char buf[256];
	int readBytes;
	char message[256];
	int tag;
	long lLen;
	long vLen;
	long callEvePos;
	long callEveEndPos;
	long callEveLength;
	int isStruct;
	int recordNumber;
	int groupType;
	int i;	
	char fullFileName[512];
	char csvFileName[512];
	CallEvent callEvent;
	
	
	
	sprintf(fullFileName,"%s%s",RECV_DIR,fileName);
	sprintf(csvFileName,"%s%s.csv",LOCAL_CSV_DIR,fileName);
	
	sprintf(message,"Make %s\n",csvFileName);
	logMessage(message);
	printfInColor(message,3);
	
	//Open and read the NRTRDE file

	fp=fopen(fullFileName,"r");

	if(fp == NULL)
		return FAIL;
		
	//get the file no of this file
	fi=fileno(fp);
	
	//read the NRTRDE header
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return FAIL;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		//get the position of the CallEventList
		if(tag == getTagByName("CallEventList"))
		{
			callEvePos=ftell(fp)-1;
			//printf("callEvePos=%ld\n",callEvePos);
		}	

		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
					if(tag == getTagByName("CallEventList"))
					{
						callEveEndPos=callEvePos+vLen+lLen+2;		
						callEveLength=vLen;
						break;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return FAIL;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
				}
				if(tag == getTagByName("CallEventList"))
				{
					callEveEndPos=callEvePos+vLen+lLen+1;		
					callEveLength=vLen;
					break;
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return FAIL;
		}		
	}	
	
	//read the NRTRDE CallEventList
	recordNumber=0;
	lseek(fi,callEvePos,SEEK_SET);
	while((readBytes=read(fi,buf,1))==1)
	{
		callEveLength-=readBytes;
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				callEveLength-=readBytes;
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return FAIL;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		if(tag == getTagByName("Moc"))
		{
			if(recordNumber > 0)
			{
				//write the MOC to local csv file
				//printCallEvent(&callEvent);
				writeCallEvent(csvFileName,&callEvent);
			}
			recordNumber++;
			groupType=2;
			//clear the CallEvent object
			memset(&callEvent,0,sizeof(CallEvent));
			callEvent.type=1;
			
		}	
		else if(tag == getTagByName("Mtc"))
		{
			
			if(recordNumber > 0)
			{
				//write the MTC to local csv file
				writeCallEvent(csvFileName,&callEvent);
				//printCallEvent(&callEvent);
			}
			recordNumber++;
			groupType=3;
			//clear the CallEvent object
			memset(&callEvent,0,sizeof(CallEvent));
			callEvent.type=2;
			
		}
		else if(tag == getTagByName("Gprs"))
		{
			if(recordNumber > 0)
			{
				//do nothing
				;
			}
			recordNumber++;
			groupType=4;
			//clear the CallEvent object
			memset(&callEvent,0,sizeof(CallEvent));
		}	
		
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			callEveLength-=readBytes;
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					callEveLength-=readBytes;
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
						callEveLength-=readBytes;
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return FAIL;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
					callEveLength-=readBytes;
					
					writeField(tag,vLen,buf,&callEvent);
				}
				
			}
			//The CallEventList is finish
			if(callEveLength<0)
			{	
				break;
			}	
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return FAIL;
		}		
	}
	
	//write the last cdr record to the local csv file
	if(recordNumber > 0)
	{
		callEvent.type=groupType-1;
		//printCallEvent(&callEvent);
		writeCallEvent(csvFileName,&callEvent);
		//checkGrp(cdrGrpTagFlag,groupType,recordNumber,fileName,senderTadig);
	}
	
	//read the NRTRDE tail
	groupType=1;
	lseek(fi,callEveEndPos,SEEK_SET);
	while((readBytes=read(fi,buf,1))==1)
	{
		if((buf[0] & 0x20) == 0x20)
		{
			isStruct=1;
		}
		else
		{
			isStruct=0;
		}		
		
		//parse tag
		//the tag have 2 bytes
		if((buf[0] & 0x1F) == 0x1F)
		{
			if((readBytes=read(fi,buf,1))==1)
			{
				tag=buf[0] & 0xFF;
			}
			else
			{
				sprintf(message,"Parse file=%s error!\n",fileName);
				logMessage(message);
				printfInColor(message,1);
				close(fi);
				fclose(fp);
				return FAIL;
			}		
		}
		//the tag have 1 byte
		else
		{
			tag=buf[0] & 0x1F;
		}	
		
		//printf("tag=%d\n",tag);
		
		//parse length
		if((readBytes=read(fi,buf,1))==1)
		{
			//the length have more than 1 byte
			if(buf[0] & 0x80)
			{
				lLen=buf[0] & 0x7F;
				
				if((readBytes=read(fi,buf,lLen))==lLen)
				{	
					vLen=0;
					for(i=0;i<lLen;i++)
					{
						vLen=vLen*256+buf[i];
					}
					if(!isStruct)
					{	
						readBytes=read(fi,buf,vLen);
					}
				}
				else
				{
					sprintf(message,"Parse file=%s error!\n",fileName);
					logMessage(message);
					printfInColor(message,1);
					close(fi);
					fclose(fp);
					return FAIL;
				}	
			}
			//the length have 1 byte
			else
			{
				vLen=buf[0] & 0x7F;
				if(!isStruct)
				{	
					readBytes=read(fi,buf,vLen);
				}
			}
		}	
		else
		{
			sprintf(message,"Parse file=%s error!\n",fileName);
			logMessage(message);
			printfInColor(message,1);
			close(fi);
			fclose(fp);
			return FAIL;
		}		
	}

	close(fi);
	fclose(fp);
	
	return SUCCESSFUL;
}

/*************************************************
Function:        // writeField
Description:     // Write one field to CallEvent object
Calls:           // decodeASCII; decodeInteger; decodeBCD;
Called By:       // createLocCSV;
Table Accessed:  // 
Table Updated:   // 
Input:           // tag:the tag of the field;
										len:the length of the field; 
										value:the value of the field; 
										callEvent:the object to store
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void writeField(int tag,int len,unsigned char* value,CallEvent* callEvent)
{
	
	char valueStr[32];
	long valuelong;
	
	//for test
	/*
	int i;
	printf("\ntag=%d,len=%d\n",tag,len);
	for(i=0;i<len;i++)
	{
		printf("%02x ",value[i]);
	}
	*/
	
	memset(valueStr,0,32);
	valuelong=0;
	switch(tags[tag].code)
	{
		//code in Integer
		case 1:
			decodeInteger(len,value,&valuelong);
			if(tag == getTagByName("CallEventDuration"))
			{
				callEvent->callDuration=valuelong;
			}	
			else if(tag == getTagByName("CauseForTermination"))
			{
				callEvent->causeForTerm=valuelong;
			}	
			else if(tag == getTagByName("CallReference"))
			{
				callEvent->callReference=valuelong;
			}	
			else if(tag == getTagByName("ChargeAmount"))
			{
				callEvent->chargeAmount=valuelong;
			}	
			
			break;
		//code in ASCII	
		case 2:
		//code in HexASCII
		case 3:
		//code in NumberASCII	
		case 4:
			decodeASCII(len,value,valueStr);
			if(tag == getTagByName("CallEventStartTimeStamp"))
			{
				sprintf(callEvent->startTime,"%s",valueStr);
			}	
			else if(tag == getTagByName("UtcTimeOffset"))
			{
				sprintf(callEvent->utcTimeOff,"%s",valueStr);
			}	
			else if(tag == getTagByName("TeleServiceCode"))
			{
				sprintf(callEvent->teleServCode,"%s",valueStr);
			}	
			else if(tag == getTagByName("BearerServiceCode"))
			{
				sprintf(callEvent->bearerServCode,"%s",valueStr);
			}	
			else if(tag == getTagByName("SupplementaryServiceCode"))
			{
				sprintf(callEvent->supplServCode,"%s",valueStr);
			}	
			else if(tag == getTagByName("DialledDigits"))
			{
				sprintf(callEvent->dialledDigits,"%s",valueStr);
			}	
			else if(tag == getTagByName("ConnectedNumber"))
			{
				sprintf(callEvent->connectedNumber,"%s",valueStr);
			}	
			else if(tag == getTagByName("ThirdPartyNumber"))
			{
				sprintf(callEvent->thirdPartyNumber,"%s",valueStr);
			}	
			else if(tag == getTagByName("CallingNumber"))
			{
				sprintf(callEvent->callingNumber,"%s",valueStr);
			}		
			else if(tag == getTagByName("RecEntityId"))
			{
				sprintf(callEvent->recEntityId,"%s",valueStr);
			}	

			break;
		//code in BCDString	
		case 5:
			decodeBCD(len,value,valueStr);
			if(tag == getTagByName("Imsi"))
			{
				sprintf(callEvent->imsi,"%s",valueStr);
			}	
			else if(tag == getTagByName("Imei"))
			{
				sprintf(callEvent->imei,"%s",valueStr);
			}	
			break;
		default:
			decodeASCII(len,value,valueStr);			
			break;
	}
	
	
}

/*************************************************
Function:        // writeCallEvent
Description:     // Write the callEvent to the local csv file
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file name of the csv file; callEvent:the call event;
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void writeCallEvent(char* fileName,CallEvent* callEvent)
{
	char command[1024];
	
	if(fileName == NULL)
		return;
	
	sprintf(command,"echo '%s,%s,%s,%s,%ld,%d,%s,%s,%s,%s,%s,%s,%s,%s,%ld,%ld' >>%s",
									 callEvent->imsi,
									 callEvent->imei,
									 callEvent->startTime,
									 callEvent->utcTimeOff,
									 callEvent->callDuration,
									 callEvent->causeForTerm,
									 callEvent->teleServCode,
									 callEvent->bearerServCode,
									 callEvent->supplServCode,
									 callEvent->dialledDigits,
									 callEvent->connectedNumber,
									 callEvent->thirdPartyNumber,
									 callEvent->callingNumber,
									 callEvent->recEntityId,
									 callEvent->callReference,
									 callEvent->chargeAmount,
									 fileName);
	system(command);								 
		
}

/*************************************************
Function:        // decodeASCII
Description:     // Decode the byte value to ascii string
Calls:           // 
Called By:       // writeField
Table Accessed:  // 
Table Updated:   // 
Input:           // len:the length of bytes; value:the value of field
Output:          // 
Return:          // result:the result has decoded;
Others:          // 
*************************************************/
void decodeASCII(int len,unsigned char* value,char* result)
{
	int i;
	
	if(len == 0 || len > 32)
	{	
		return;
	}
	
	for(i=0;i<len;i++)
	{
		result[i]=value[i];
	}	
	result[i]='\0';
}

/*************************************************
Function:        // decodeInteger
Description:     // Decode the bytes value to integer
Calls:           // 
Called By:       // writeField
Table Accessed:  // 
Table Updated:   // 
Input:           // len:the length of bytes; value:the value of field
Output:          // 
Return:          // result:the result has decoded;
Others:          // 
*************************************************/
void decodeInteger(int len,unsigned char* value,long* result)
{
	int i;
	
	if(len == 0)
	{
		return;
	}
	
	*result=0;
	for(i=0;i<len;i++)
	{
		*result=*result*256+value[i];
	}	
}

/*************************************************
Function:        // decodeBCD
Description:     // Decode the byte value to BCD string
Calls:           // 
Called By:       // writeField
Table Accessed:  // 
Table Updated:   // 
Input:           // len:the length of bytes; value:the value of field
Output:          // 
Return:          // result:the result has decoded;
Others:          // 
*************************************************/
void decodeBCD(int len,unsigned char* value,char* result)
{
	int i;
	int headByte;
	int tailByte;
	int index;
	
	if(len == 0 || len > 32)
	{
		return;
	}
	
	index=0;
	for(i=0;i<len;i++)
	{
		headByte=value[i] & 0xF0;
		headByte>>=4;
		tailByte=value[i] & 0x0F;
		if(headByte != 0x0F)
		{
			result[index++]=headByte+0x30;
		}	
		if(tailByte != 0x0F)
		{
			result[index++]=tailByte+0x30;
		}	
	}	
	
			
}

/*************************************************
Function:        // printCallEvent
Description:     // Print the callEvent object
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // callEvent:The callEvent object;
Output:          // 
Return:          // 
Others:          // For test
*************************************************/
void printCallEvent(CallEvent* callEvent)
{
	
	printf("-------------------------------\n");
	printf("type=%d\n",callEvent->type);
	printf("Imsi=%s\n",callEvent->imsi);
	printf("Imei=%s\n",callEvent->imei);
	printf("CallEventStartTime=%s\n",callEvent->startTime);
	printf("UtcTimeOffset=%s\n",callEvent->utcTimeOff);
	printf("CallEventDuration=%ld\n",callEvent->callDuration);
	printf("CauseForTermination=%d\n",callEvent->causeForTerm);
	printf("teleServCode=%s\n",callEvent->teleServCode);
	printf("bearerServCode=%s\n",callEvent->bearerServCode);
	printf("supplServCode=%s\n",callEvent->supplServCode);
	printf("dialledDigits=%s\n",callEvent->dialledDigits);
	printf("connectedNumber=%s\n",callEvent->connectedNumber);
	printf("thirdPartyNumber=%s\n",callEvent->thirdPartyNumber);
	printf("callingNumber=%s\n",callEvent->callingNumber);
	printf("recEntityId=%s\n",callEvent->recEntityId);
	printf("callReference=%ld\n",callEvent->callReference);
	printf("chargeAmount=%ld\n",callEvent->chargeAmount);
	
}

/*************************************************
Function:        // isValidInGroup
Description:     // Judge the tag whether is valid in the group
Calls:           // 
Called By:       // noConfuseInGrp;
Table Accessed:  // 
Table Updated:   // 
Input:           // tag:the tag value; type:1-nrtrde; 2-MOC; 3-MTC; 4-GPRS
Output:          // 
Return:          // 1:valid; 0:unvalid
Others:          // Use for parse the NRTRDE file
*************************************************/
int isValidInGroup(int tag,int type)
{
	int result;
	
	//NRTRDE group
	if(type == 1)
	{
		if(tag == getTagByName("Nrtrde")||
			 tag == getTagByName("CallEventList")||
			 tag == getTagByName("CallEventsCount")||
			 tag == getTagByName("FileAvailableTimeStamp")||
			 tag == getTagByName("Recipient")||
			 tag == getTagByName("ReleaseVersionNumber")||
			 tag == getTagByName("Sender")||
			 tag == getTagByName("SequenceNumber")||
			 tag == getTagByName("SpecificationVersionNumber")||
			 tag == getTagByName("UtcTimeOffset"))
		{
			result=1;
		}	
		else
		{
			result=0;
		}	 
	}	
	//MOC group
	else if(type == 2)
	{
		if(tag == getTagByName("Moc")||
			 tag == getTagByName("BearerServiceCode")||
			 tag == getTagByName("CallEventDuration")||
			 tag == getTagByName("CallEventStartTimeStamp")||
			 tag == getTagByName("CallReference")||
			 tag == getTagByName("CauseForTermination")||
			 tag == getTagByName("ChargeAmount")||
			 tag == getTagByName("ConnectedNumber")||
			 tag == getTagByName("DialledDigits")||
			 tag == getTagByName("Imei")||
			 tag == getTagByName("Imsi")||
			 tag == getTagByName("RecEntityId")||
			 tag == getTagByName("SupplementaryServiceCode")||
			 tag == getTagByName("TeleServiceCode")||
			 tag == getTagByName("ThirdPartyNumber")||
			 tag == getTagByName("UtcTimeOffset")||
			 tag == getTagByName("ServiceCode"))
		{
			result=1;
		}	
		else
		{
			result=0;
		}		
	}	
	//MTC group
	else if(type == 3)
	{
		if(tag == getTagByName("Mtc")||
			 tag == getTagByName("BearerServiceCode")||
			 tag == getTagByName("CallEventDuration")||
			 tag == getTagByName("CallEventStartTimeStamp")||
			 tag == getTagByName("CallingNumber")||
			 tag == getTagByName("CallReference")||
			 tag == getTagByName("CauseForTermination")||
			 tag == getTagByName("ChargeAmount")||
			 tag == getTagByName("Imei")||
			 tag == getTagByName("Imsi")||
			 tag == getTagByName("RecEntityId")||
			 tag == getTagByName("TeleServiceCode")||
			 tag == getTagByName("UtcTimeOffset")||
			 tag == getTagByName("ServiceCode"))
		{
			result=1;
		}	
		else
		{
			result=0;
		}		
	}	
	//GPRS group
	else if(type == 4)
	{
		if(tag == getTagByName("Gprs")||
			 tag == getTagByName("AccessPointNameNI")||
			 tag == getTagByName("AccessPointNameOI")||
			 tag == getTagByName("CallEventDuration")||
			 tag == getTagByName("CallEventStartTimeStamp")||
			 tag == getTagByName("CauseForTermination")||
			 tag == getTagByName("ChargingId")||
			 tag == getTagByName("DataVolumeIncoming")||
		   tag == getTagByName("DataVolumeOutgoing")||
		   tag == getTagByName("GgsnAddress")||
		   tag == getTagByName("Imei")||
		   tag == getTagByName("Imsi")||
		   tag == getTagByName("SgsnAddress")||
		   tag == getTagByName("UtcTimeOffset"))
		{
			result=1;
		}	
		else
		{
			result=0;
		}		
	}	
	return result;
}

/*************************************************
Function:        // checkGrp
Description:     // Check whether there are some Mandatory tag missing in the group
Calls:           // addNENodeInDB;
Called By:       // noTagMissInGrp;
Table Accessed:  // 
Table Updated:   // 
Input:           // groupFlag:the group 50 flags;
										groupType:1-NRTRDE; 2-MOC; 3-MTC; 4-GPRS;
										recordNumber:the record number in the NRTRDE file;
										fileName:the name of the NRTRDE file;
										senderTadig:the tadig of the sender;
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void checkGrp(int* groupFlag,int groupType,int recordNumber,char* fileName,char* senderTadig)
{
	char message[256];
	
	/*
	int i;
	printf("check grp,groupType=%d,recordNumber=%d\n",groupType,recordNumber);
	for(i=0;i<50;i++)
	{
		
		printf("tag=%d,flag=%d",i,*groupFlag);
		if(*groupFlag != 0)
			printf("(%s)",tags[i].fieldName);
		groupFlag++;	
		printf("\n");	
	}
	*/

	switch(groupType)
	{
		//NRTRDE group
		case 1:
			//UtcTimeOffset miss, Error Code 301
			if(groupFlag[getTagByName("UtcTimeOffset")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,0,"301");
				sprintf(message,"The file=%s miss tag=%d(UtcTimeOffset) in the NRTRDE group,Error Code(301)\n",fileName,getTagByName("UtcTimeOffset"));
				logMessage(message);
				printfInColor(message,1);
			}	
			//SpecificationVersionNumber miss, Error Code 326
			if(groupFlag[getTagByName("SpecificationVersionNumber")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,0,"326");
				sprintf(message,"The file=%s miss tag=%d(SpecificationVersionNumber) in the NRTRDE group,Error Code(326)\n",fileName,getTagByName("SpecificationVersionNumber"));
				logMessage(message);
				printfInColor(message,1);
			}
			//ReleaseVersionNumber miss, Error Code 332
			if(groupFlag[getTagByName("ReleaseVersionNumber")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,0,"332");
				sprintf(message,"The file=%s miss tag=%d(ReleaseVersionNumber) in the NRTRDE group,Error Code(332)\n",fileName,getTagByName("ReleaseVersionNumber"));
				logMessage(message);
				printfInColor(message,1);
			}
			//Sender miss, Error Code 327
			if(groupFlag[getTagByName("Sender")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,0,"327");
				sprintf(message,"The file=%s miss tag=%d(Sender) in the NRTRDE group,Error Code(327)\n",fileName,getTagByName("Sender"));
				logMessage(message);
				printfInColor(message,1);
			}		
			//Recipient miss, Error Code 328
			if(groupFlag[getTagByName("Recipient")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,0,"328");
				sprintf(message,"The file=%s miss tag=%d(Recipient) in the NRTRDE group,Error Code(328)\n",fileName,getTagByName("Recipient"));
				logMessage(message);
				printfInColor(message,1);
			}	
			//SequenceNumber miss, Error Code 329
			if(groupFlag[getTagByName("SequenceNumber")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,0,"329");
				sprintf(message,"The file=%s miss tag=%d(SequenceNumber) in the NRTRDE group,Error Code(329)\n",fileName,getTagByName("SequenceNumber"));
				logMessage(message);
				printfInColor(message,1);
			}
			//FileAvailableTimeStamp miss, Error Code 330
			if(groupFlag[getTagByName("FileAvailableTimeStamp")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,0,"330");
				sprintf(message,"The file=%s miss tag=%d(FileAvailableTimeStamp) in the NRTRDE group,Error Code(330)\n",fileName,getTagByName("FileAvailableTimeStamp"));
				logMessage(message);
				printfInColor(message,1);
			}
			//CallEventsCount miss, Error Code 331
			if(groupFlag[getTagByName("CallEventsCount")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,0,"331");
				sprintf(message,"The file=%s miss tag=%d(CallEventsCount) in the NRTRDE group,Error Code(331)\n",fileName,getTagByName("CallEventsCount"));
				logMessage(message);
				printfInColor(message,1);
			}
				
			break;
		//MOC	group
		case 2:	
			//Imsi miss, Error Code 312
			if(groupFlag[getTagByName("Imsi")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"312");
				sprintf(message,"The file=%s miss tag=%d(Imsi) in the MOC group,recordNumber=%d,Error Code(312)\n",fileName,getTagByName("Imsi"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//CallEventStartTimeStamp, Error Code 313
			if(groupFlag[getTagByName("CallEventStartTimeStamp")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"313");
				sprintf(message,"The file=%s miss tag=%d(CallEventStartTimeStamp) in the MOC group,recordNumber=%d,Error Code(313)\n",fileName,getTagByName("CallEventStartTimeStamp"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//UtcTimeOffset miss, Error Code 300
			if(groupFlag[getTagByName("UtcTimeOffset")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"300");
				sprintf(message,"The file=%s miss tag=%d(UtcTimeOffset) in the MOC group,recordNumber=%d,Error Code(300)\n",fileName,getTagByName("UtcTimeOffset"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//CallEventDuration miss, Error Code 314
			if(groupFlag[getTagByName("CallEventDuration")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"314");
				sprintf(message,"The file=%s miss tag=%d(CallEventDuration) in the MOC group,recordNumber=%d,Error Code(314)\n",fileName,getTagByName("CallEventDuration"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//CauseForTermination miss, Error Code 315
			if(groupFlag[getTagByName("CauseForTermination")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"315");
				sprintf(message,"The file=%s miss tag=%d(CauseForTermination) in the MOC group,recordNumber=%d,Error Code(315)\n",fileName,getTagByName("CauseForTermination"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			
			//ServiceCode(Neither of TeleServiceCode and BearerServiceCode present in the MOC group), Error Code 316
			if(groupFlag[getTagByName("ServiceCode")] == 0 || 
					(groupFlag[getTagByName("ServiceCode")] == 1 && groupFlag[getTagByName("TeleServiceCode")] == 0 && groupFlag[getTagByName("BearerServiceCode")] == 0))
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"316");
				sprintf(message,"The file=%s miss the tag=%d(ServiceCode),neither of the tag=%d(TeleServiceCode) and tag=%d(BearerServiceCode) present in the MOC group,recordNumber=%d,Error Code(316)\n",
					fileName,getTagByName("ServiceCode"),getTagByName("TeleServiceCode"),getTagByName("BearerServiceCode"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}		
			//RecEntityId miss,Error Code 317
			if(groupFlag[getTagByName("RecEntityId")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"317");
				sprintf(message,"The file=%s miss tag=%d(RecEntityId) in the MOC group,recordNumber=%d,Error Code(317)\n",fileName,getTagByName("RecEntityId"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//both DialledDigits and ConnectedNumber miss, Error Code 333
			if(groupFlag[getTagByName("DialledDigits")] == 0 && groupFlag[getTagByName("ConnectedNumber")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"333");
				sprintf(message,"The file=%s miss both tag=%d(DialledDigits) and tag=%d(ConnectedNumber) in the MOC group,recordNumber=%d,Error Code(333)\n",fileName,getTagByName("DialledDigits"),getTagByName("ConnectedNumber"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			/*
			//ConnectedNumber miss, Error Code 334
			if(groupFlag[getTagByName("ConnectedNumber")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"334");
				sprintf(message,"The file=%s miss tag=%d(ConnectedNumber) in the MOC group,recordNumber=%d,Error Code(334)\n",fileName,getTagByName("ConnectedNumber"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			*/
			break;
		//MTC group	
		case 3:
			//Imsi miss, Error Code 319
			if(groupFlag[getTagByName("Imsi")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"319");
				sprintf(message,"The file=%s miss tag=%d(Imsi) in the MTC group,recordNumber=%d,Error Code(319)\n",fileName,getTagByName("Imsi"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//CallEventStartTimeStamp, Error Code 320
			if(groupFlag[getTagByName("CallEventStartTimeStamp")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"320");
				sprintf(message,"The file=%s miss tag=%d(CallEventStartTimeStamp) in the MTC group,recordNumber=%d,Error Code(320)\n",fileName,getTagByName("CallEventStartTimeStamp"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//UtcTimeOffset miss, Error Code 300
			if(groupFlag[getTagByName("UtcTimeOffset")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"300");
				sprintf(message,"The file=%s miss tag=%d(UtcTimeOffset) in the MTC group,recordNumber=%d,Error Code(300)\n",fileName,getTagByName("UtcTimeOffset"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}
			//CallEventDuration miss, Error Code 321
			if(groupFlag[getTagByName("CallEventDuration")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"321");
				sprintf(message,"The file=%s miss tag=%d(CallEventDuration) in the MTC group,recordNumber=%d,Error Code(321)\n",fileName,getTagByName("CallEventDuration"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//CauseForTermination miss, Error Code 322
			if(groupFlag[getTagByName("CauseForTermination")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"322");
				sprintf(message,"The file=%s miss tag=%d(CauseForTermination) in the MTC group,recordNumber=%d,Error Code(322)\n",fileName,getTagByName("CauseForTermination"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//ServiceCode(Neither of TeleServiceCode and BearerServiceCode present in the MOC group), Error Code 323
			if(groupFlag[getTagByName("ServiceCode")] == 0 || 
					(groupFlag[getTagByName("ServiceCode")] == 1 && groupFlag[getTagByName("TeleServiceCode")] == 0 && groupFlag[getTagByName("BearerServiceCode")] == 0))
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"323");
				sprintf(message,"The file=%s miss the tag=%d(ServiceCode),neither of the tag=%d(TeleServiceCode) and tag=%d(BearerServiceCode) present in the MTC group,recordNumber=%d,Error Code(323)\n",
					fileName,getTagByName("ServiceCode"),getTagByName("TeleServiceCode"),getTagByName("BearerServiceCode"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}		
			//RecEntityId miss,Error Code 324
			if(groupFlag[getTagByName("RecEntityId")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"324");
				sprintf(message,"The file=%s miss tag=%d(RecEntityId) in the MTC group,recordNumber=%d,Error Code(324)\n",fileName,getTagByName("RecEntityId"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			break;	
		//GPRS group
		case 4:
			//Imsi miss, Error Code 302
			if(groupFlag[getTagByName("Imsi")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"302");
				sprintf(message,"The file=%s miss tag=%d(Imsi) in the GPRS group,recordNumber=%d,Error Code(302)\n",fileName,getTagByName("Imsi"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//CallEventStartTimeStamp, Error Code 303
			if(groupFlag[getTagByName("CallEventStartTimeStamp")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"303");
				sprintf(message,"The file=%s miss tag=%d(CallEventStartTimeStamp) in the GPRS group,recordNumber=%d,Error Code(303)\n",fileName,getTagByName("CallEventStartTimeStamp"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			if(groupFlag[getTagByName("UtcTimeOffset")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"300");
				sprintf(message,"The file=%s miss tag=%d(UtcTimeOffset) in the GPRS group,recordNumber=%d,Error Code(300)\n",fileName,getTagByName("UtcTimeOffset"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}
			//CallEventDuration miss, Error Code 304
			if(groupFlag[getTagByName("CallEventDuration")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"304");
				sprintf(message,"The file=%s miss tag=%d(CallEventDuration) in the GPRS group,recordNumber=%d,Error Code(304)\n",fileName,getTagByName("CallEventDuration"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//CauseForTermination miss, Error Code 305
			if(groupFlag[getTagByName("CauseForTermination")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"305");
				sprintf(message,"The file=%s miss tag=%d(CauseForTermination) in the GPRS group,recordNumber=%d,Error Code(305)\n",fileName,getTagByName("CauseForTermination"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//AccessPointNameNI miss, Error Code 306
			if(groupFlag[getTagByName("AccessPointNameNI")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"306");
				sprintf(message,"The file=%s miss tag=%d(AccessPointNameNI) in the GPRS group,recordNumber=%d,Error Code(306)\n",fileName,getTagByName("AccessPointNameNI"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//DataVolumeIncoming miss, Error Code 307
			if(groupFlag[getTagByName("DataVolumeIncoming")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"307");
				sprintf(message,"The file=%s miss tag=%d(DataVolumeIncoming) in the GPRS group,recordNumber=%d,Error Code(307)\n",fileName,getTagByName("DataVolumeIncoming"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//DataVolumeOutgoing miss, Error Code 308
			if(groupFlag[getTagByName("DataVolumeOutgoing")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"308");
				sprintf(message,"The file=%s miss tag=%d(DataVolumeOutgoing) in the GPRS group,recordNumber=%d,Error Code(308)\n",fileName,getTagByName("DataVolumeOutgoing"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//SgsnAddress miss, Error Code 309
			if(groupFlag[getTagByName("SgsnAddress")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"309");
				sprintf(message,"The file=%s miss tag=%d(SgsnAddress) in the GPRS group,recordNumber=%d,Error Code(309)\n",fileName,getTagByName("SgsnAddress"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//GgsnAddress miss, Error Code 310
			if(groupFlag[getTagByName("GgsnAddress")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"310");
				sprintf(message,"The file=%s miss tag=%d(GgsnAddress) in the GPRS group,recordNumber=%d,Error Code(310)\n",fileName,getTagByName("GgsnAddress"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			//ChargingId miss, Error Code 311
			if(groupFlag[getTagByName("ChargingId")] == 0)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"311");
				sprintf(message,"The file=%s miss tag=%d(ChargingId) in the GPRS group,recordNumber=%d,Error Code(311)\n",fileName,getTagByName("ChargingId"),recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
			break;
		default:
			break;			
	}
}

/*************************************************
Function:        // checkTag
Description:     // Parse the tag value and check out the error
Calls:           // 
Called By:       // checkTagDetail;
Table Accessed:  // 
Table Updated:   // 
Input:           //	groupType:1-NRTRDE; 2-MOC; 3-MTC; 4-GPRS;
										recordNumber:the record number in the NRTRDE file;
										fileName:the name of the NRTRDE file;
										senderTadig:the tadig of the sender;
										tag:the tag value;
										len:the length of the value;
										value:the byte value of the tag;
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void checkTag(int groupType,int recordNumber,char* fileName,char* senderTadig,int tag,int len,unsigned char* value)
{
	char message[512];
	char groupString[16];
	char tempStr[64];
	int i;
	
	/*
	printf("groupType=%d\n",groupType);
	printf("recordNumber=%d\n",recordNumber);
	printf("fieldName=%s\n",fileName);
	printf("senderTadig=%s\n",senderTadig);
	printf("tag=%d(%s)\n",tag,tags[tag].fieldName);
	printf("len=%d\n",len);
	for(i=0;i<len;i++)
	{
		printf("%02x ",value[i]);
	}
	printf("\n");
	*/
	if(groupType == 1)
	{
		sprintf(groupString,"NRTRDE");
	}	
	else if(groupType == 2)
	{
		sprintf(groupString,"MOC");
	}	
	else if(groupType == 3)
	{
		sprintf(groupString,"MTC");
	}	
	else if(groupType == 4)
	{
		sprintf(groupString,"GPRS");
	}	
	

	//check the AccessPointNameNI
	if(tag == getTagByName("AccessPointNameNI"))
	{
		//Syntax error, length valid, Error Code 100
		if(len < tags[tag].minSize || len > tags[tag].maxSize)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"100");
			sprintf(message,"The file=%s tag=%d(AccessPointNameNI) has a syntax error(length out of(%d,%d)) in the GPRS group,recordNumber=%d,Error Code(100)\n",fileName,tag,tags[tag].minSize,tags[tag].maxSize,recordNumber);
			logMessage(message);
			printfInColor(message,1);
		}	
	}
	//check the AccessPointNameOI
	else if(tag == getTagByName("AccessPointNameOI"))
	{
		//Syntax error, length valid, Error Code 101
		if(len < tags[tag].minSize || len > tags[tag].maxSize)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"101");
			sprintf(message,"The file=%s tag=%d(AccessPointNameOI) has a syntax error(length out of(%d,%d)) in the GPRS group,recordNumber=%d,Error Code(101)\n",fileName,tag,tags[tag].minSize,tags[tag].maxSize,recordNumber);
			logMessage(message);
			printfInColor(message,1);
		}	
	}
	//check the BearerServiceCode 
	else if(tag == getTagByName("BearerServiceCode"))
	{
		//the length is not 2, syntax error, Error Code 102
		if(len != 2)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"102");
			sprintf(message,"The file=%s tag=%d(BearerServiceCode) has a syntax error(length out of(%d,%d)) in the %s group,Error Code(102)\n",fileName,tag,tags[tag].minSize,tags[tag].maxSize,groupString);
			logMessage(message);
			printfInColor(message,1);
		}	
		else 
		{
			//the value is not 0x00,0x20,0x21,0x22,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x30,0x32,0x34,0x35
			//0x36,0x37,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x50,0x54,0x55,0x56,0x57,0x60,0x70,0x80,0x90,0xA0,0xB0,0xC0,0xD0 
			//value out of range, Error Code 200
			for(i=0;i<len;i++)
			{
				tempStr[i]=value[i];
			}
			tempStr[i]='\0';
			if(!(strcasecmp(tempStr,"00") == 0 ||
				   strcasecmp(tempStr,"20") == 0 || 
				   strcasecmp(tempStr,"21") == 0 ||
				   strcasecmp(tempStr,"22") == 0 ||
				   strcasecmp(tempStr,"23") == 0 ||
				   strcasecmp(tempStr,"24") == 0 ||
				   strcasecmp(tempStr,"25") == 0 ||
				   strcasecmp(tempStr,"26") == 0 ||
				   strcasecmp(tempStr,"27") == 0 ||
				   strcasecmp(tempStr,"30") == 0 ||
				   strcasecmp(tempStr,"32") == 0 ||
				   strcasecmp(tempStr,"34") == 0 ||
				   strcasecmp(tempStr,"35") == 0 ||
				   strcasecmp(tempStr,"36") == 0 ||
				   strcasecmp(tempStr,"37") == 0 ||
				   strcasecmp(tempStr,"40") == 0 ||
				   strcasecmp(tempStr,"41") == 0 ||
				   strcasecmp(tempStr,"42") == 0 ||
				   strcasecmp(tempStr,"43") == 0 ||
				   strcasecmp(tempStr,"44") == 0 ||
				   strcasecmp(tempStr,"45") == 0 ||
				   strcasecmp(tempStr,"46") == 0 ||
				   strcasecmp(tempStr,"47") == 0 ||
				   strcasecmp(tempStr,"50") == 0 ||
				   strcasecmp(tempStr,"54") == 0 ||
				   strcasecmp(tempStr,"55") == 0 ||
				   strcasecmp(tempStr,"56") == 0 ||
				   strcasecmp(tempStr,"57") == 0 ||
				   strcasecmp(tempStr,"60") == 0 ||
				   strcasecmp(tempStr,"70") == 0 ||
				   strcasecmp(tempStr,"80") == 0 ||
				   strcasecmp(tempStr,"90") == 0 ||
				   strcasecmp(tempStr,"A0") == 0 ||
				   strcasecmp(tempStr,"B0") == 0 ||
				   strcasecmp(tempStr,"C0") == 0 ||
				   strcasecmp(tempStr,"D0") == 0))
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"200");
				sprintf(message,"The file=%s tag=%d(BearerServiceCode) has a value out of range error(0x00,0x20,0x21,0x22,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x30,0x32,0x34,0x35,0x36,0x37,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x50,0x54,0x55,0x56,0x57,0x60,0x70,0x80,0x90,0xA0,0xB0,0xC0,0xD0) in the %s group,Error Code(200)\n",fileName,tag,groupString);
				logMessage(message);
				printfInColor(message,1);
			}	
		}	
	}	
	//check the CallEventDuration 
	else if(tag == getTagByName("CallEventDuration"))
	{
		int callDuration;
		callDuration=0;
		for(i=0;i<len;i++)
		{
			callDuration=callDuration*256+value[i];
		}
		//CallEventDuration greater than the Required Timescale, Error Code 800
		if(callDuration>g_maxCallDuration)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"800");
			sprintf(message,"The file=%s tag=%d(CallEventDuration) is greater than the Required Timescale in the %s group,recordNumber=%d,Error Code(800)\n",fileName,tag,groupString,recordNumber);
			logMessage(message);
			printfInColor(message,1);
		}	
		//printf("callDuration=%d\n",callDuration);
	}
	//check the CallEventsCount
	else if(tag == getTagByName("CallEventsCount"))
	{
		
	}	
	//check the CallEventStartTimeStamp
	else if(tag == getTagByName("CallEventStartTimeStamp"))
	{
		//the length is not 14, syntax error, 20071212032323, Error Code 104
		if(len != 14)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"104");
			sprintf(message,"The file=%s tag=%d(CallEventStartTimeStamp) has a syntax error(length out of(%d,%d)) in the %s group,recordNumber=%d,Error Code(104)\n",fileName,tag,tags[tag].minSize,tags[tag].maxSize,groupString,recordNumber);
			logMessage(message);
			printfInColor(message,1);
		}	
		else
		{
			//the value is out of(0x30,0x39), value out of the range, Error Code 202
			for(i=0;i<len;i++)
			{
				if(value[i]>0x39 || value[i]<0x30)
				{
					addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"202");
					sprintf(message,"The file=%s tag=%d(CallEventStartTimeStamp) has a value out of range error in the %s group,recordNumber=%d,Error Code(202)\n",fileName,tag,groupString,recordNumber);
					logMessage(message);
					printfInColor(message,1);
					break;
				}	
			}
		}	
	}
	//check the CallingNumber 
	else if(tag == getTagByName("CallingNumber"))
	{
		
	}
	//check the CallReference 
	else if(tag == getTagByName("CallReference"))
	{
		
	}	
	//check the CauseForTermination 
	else if(tag == getTagByName("CauseForTermination"))
	{
		//the value is not 0-5 in MOC/MTC or not 0, 4, 5, 16, 17, 18, 19, 20 and 21 in GPRS, Error Code 204
		if(groupType == 2 || groupType == 3)
		{
			if(value[0] > 5)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"204");
				sprintf(message,"The file=%s tag=%d(CauseForTermination) has a value out of range error(0,1,2,3,4,5) in the %s group,recordNumber=%d,Error Code(204)\n",fileName,tag,groupString,recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
		}
		else if(groupType == 4)
		{
			if(!(value[0] == 0 || value[0] == 4 || value[0] == 5 ||
				   value[0] == 16 || value[0] == 17 || value[0] == 18 ||
				   value[0] == 19 || value[0] == 20 || value[0] == 21))
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"204");
				sprintf(message,"The file=%s tag=%d(CauseForTermination) has a value out of range error(0,4,5,16,17,18,19,20,21) in the %s group,recordNumber=%d,Error Code(204)\n",fileName,tag,groupString,recordNumber);
				logMessage(message);
				printfInColor(message,1);
			}	
		}		
	}
	//check the ChargeAmount 
	else if(tag == getTagByName("ChargeAmount"))
	{
		
	}
	//check the ChargingId 
	else if(tag == getTagByName("ChargingId"))
	{
		
	}
	//check the ConnectedNumber 
	else if(tag == getTagByName("ConnectedNumber"))
	{
		
	}		
	//check the DataVolumeIncoming			
	else if(tag == getTagByName("DataVolumeIncoming"))
	{
		
	}	
	//check the DataVolumeOutgoing 
	else if(tag == getTagByName("DataVolumeOutgoing"))
	{
		
	}	
	//check the DialledDigits  
	else if(tag == getTagByName("DialledDigits"))
	{
		
	}
	//check the FileAvailableTimeStamp  
	else if(tag == getTagByName("FileAvailableTimeStamp"))
	{
		//the length is not 14, syntax error, 20071212032323, Error Code 113
		if(len != 14)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"113");
			sprintf(message,"The file=%s tag=%d(FileAvailableTimeStamp) has a syntax error(length out of(%d,%d)) in the %s group,recordNumber=%d,Error Code(113)\n",fileName,tag,tags[tag].minSize,tags[tag].maxSize,groupString,recordNumber);
			logMessage(message);
			printfInColor(message,1);
		}	
		else
		{
			//the value is out of(0x30,0x39), value out of the range, Error Code 210
			for(i=0;i<len;i++)
			{
				if(value[i]>0x39 || value[i]<0x30)
				{
					addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"210");
					sprintf(message,"The file=%s tag=%d(FileAvailableTimeStamp) has a value out of range error in the %s group,recordNumber=%d,Error Code(210)\n",fileName,tag,groupString,recordNumber);
					logMessage(message);
					printfInColor(message,1);
					break;
				}	
			}
		}	
	}
	//check the GgsnAddress   
	else if(tag == getTagByName("GgsnAddress"))
	{
		
	}
	//check the Imei   
	else if(tag == getTagByName("Imei"))
	{
		
	}
	//check the Imsi   
	else if(tag == getTagByName("Imsi"))
	{
		unsigned char headByte;
		unsigned char tailByte;
		char mcc_mnc[8];
		char mcc_mnc_value[8];
		int tmp;
		
		tmp=0;
		//the value is not coded in BCD string, syntax error, Error Code 116
		for(i=0;i<len-1;i++)
		{
			headByte=value[i] & 0xF0;
			headByte >>= 4;
			tailByte=value[i] & 0x0F;
			if(headByte > 9 || tailByte > 9)
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"116");
				sprintf(message,"The file=%s tag=%d(Imsi) has a syntax error in the %s group,recordNumber=%d,Error Code(116)\n",fileName,tag,groupString,recordNumber);
				logMessage(message);
				printfInColor(message,1);
				break;
			}
			if(tmp<5)
			{
				mcc_mnc_value[tmp]=0x30+headByte;
				tmp++;
			}		
			if(tmp<5)
			{
				mcc_mnc_value[tmp]=0x30+tailByte;
				tmp++;
			}	
		}
		
		mcc_mnc_value[tmp]='\0';
		
		//the length is not (3,8), value out of range error, Error Code 211
		if(len < 3 || len > 8)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"211");
			sprintf(message,"The file=%s tag=%d(Imsi) has a syntax error(length out of(%d,%d)) in the %s group,recordNumber=%d,Error Code(211)\n",fileName,tag,tags[tag].minSize,tags[tag].maxSize,groupString,recordNumber);
			logMessage(message);
			printfInColor(message,1);
		}	
		
		//First characters are different from home operator's MCC+MNC, Error Code 801
		sprintf(mcc_mnc,"%s%s",g_local_mcc,g_local_mnc);
		//printf("mcc_mnc=%s,mcc_mnc_value=%s\n",mcc_mnc,mcc_mnc_value);
		if(strcmp(mcc_mnc_value,mcc_mnc) != 0)
		{	
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"801");
			sprintf(message,"The file=%s tag=%d(Imsi) first characters are different from home operator MCC+MNC in the %s group,recordNumber=%d,Error Code(801)\n",fileName,tag,groupString,recordNumber);
			logMessage(message);
			printfInColor(message,1);
		}
	}
	//check the RecEntityId    
	else if(tag == getTagByName("RecEntityId"))
	{
		
	}
	//check the Recipient    
	else if(tag == getTagByName("Recipient"))
	{
		//the length is not 5, syntax error, Error Code 117
		if(len != 5)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"117");
			sprintf(message,"The file=%s tag=%d(Recipient) has a syntax error(length out of(%d,%d)) in the %s group,Error Code(117)\n",fileName,tag,tags[tag].minSize,tags[tag].maxSize,groupString);
			logMessage(message);
			printfInColor(message,1);
		}	
		else
		{
			//The item does not match the Recipient on the file name, Error Code 402
			for(i=7;i<12;i++)
			{

				if(fileName[i] != value[i-7])
				{
					addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"402");
					sprintf(message,"The file=%s tag=%d(Recipient) does not match the Recipient on the file name in the %s group,Error Code(402)\n",fileName,tag,groupString);
					logMessage(message);
					printfInColor(message,1);
					break;
				}	
			}
		}	
	}
	//check the ReleaseVersionNumber     
	else if(tag == getTagByName("ReleaseVersionNumber"))
	{
		
	}
	//check the Sender     
	else if(tag == getTagByName("Sender"))
	{
		//the length is not 5, syntax error, Error Code 121
		if(len != 5)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"121");
			sprintf(message,"The file=%s tag=%d(Sender) has a syntax error(length out of(%d,%d)) in the %s group,Error Code(121)\n",fileName,tag,tags[tag].minSize,tags[tag].maxSize,groupString);
			logMessage(message);
			printfInColor(message,1);
		}	
		else
		{
			//The item does not match the Sender on the file name, Error Code 404
			for(i=2;i<7;i++)
			{

				if(fileName[i] != value[i-2])
				{
					addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"404");
					sprintf(message,"The file=%s tag=%d(Sender) does not match the Sender on the file name in the %s group,Error Code(404)\n",fileName,tag,groupString);
					logMessage(message);
					printfInColor(message,1);
					break;
				}	
			}
		}	
	}
	//check the SequenceNumber      
	else if(tag == getTagByName("SequenceNumber"))
	{
		//the length is not 7, syntax error, 0000001, Error Code 120
		if(len != 7)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"120");
			sprintf(message,"The file=%s tag=%d(SequenceNumber) has a syntax error(length out of(%d,%d)) in the %s group,Error Code(120)\n",fileName,tag,tags[tag].minSize,tags[tag].maxSize,groupString);
			logMessage(message);
			printfInColor(message,1);
		}	
		else
		{
			//the value is out of(0x30,0x39), value out of the range, Error Code 214
			for(i=0;i<len;i++)
			{
				if(value[i]>0x39 || value[i]<0x30)
				{
					addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"214");
					sprintf(message,"The file=%s tag=%d(SequenceNumber) has a value out of range error in the %s group,Error Code(214)\n",fileName,tag,groupString);
					logMessage(message);
					printfInColor(message,1);
					break;
				}	
			}
			//the value does not match the SequenceNumber on the file name, Error Code 403
			
			for(i=12;i<19;i++)
			{
				if(fileName[i] != value[i-12])
				{
					addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"403");
					sprintf(message,"The file=%s tag=%d(SequenceNumber) does not match the SequenceNumber on the file name in the %s group,Error Code(403)\n",fileName,tag,groupString);
					logMessage(message);
					printfInColor(message,1);
					break;
				}	
			}
		}	
	}
	//check the SgsnAddress       
	else if(tag == getTagByName("SgsnAddress"))
	{
		
	}
	//check the SpecificationVersionNumber       
	else if(tag == getTagByName("SpecificationVersionNumber"))
	{
		
	}
	//check the SupplementaryServiceCode        
	else if(tag == getTagByName("SupplementaryServiceCode"))
	{
		//the length is not 2, syntax error, Error Code 125
		if(len != 2)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"125");
			sprintf(message,"The file=%s tag=%d(SupplementaryServiceCode) has a syntax error(length out of(%d,%d)) in the %s group,Error Code(125)\n",fileName,tag,tags[tag].minSize,tags[tag].maxSize,groupString);
			logMessage(message);
			printfInColor(message,1);
		}	
		else 
		{
			//the value is not 0x29,0x2A,0x2B, value out of range, Error Code 217
			for(i=0;i<len;i++)
			{
				tempStr[i]=value[i];
			}
			tempStr[i]='\0';
			if(!(strcasecmp(tempStr,"29") == 0 || strcasecmp(tempStr,"2A") == 0 || strcasecmp(tempStr,"2B") == 0))
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"217");
				sprintf(message,"The file=%s tag=%d(SupplementaryServiceCode) has a value out of range error(0x29,0x2A,0x2B) in the %s group,Error Code(217)\n",fileName,tag,groupString);
				logMessage(message);
				printfInColor(message,1);
			}	
				
		}	
	}
	//check the TeleServiceCode        
	else if(tag == getTagByName("TeleServiceCode"))
	{
		//the length is not 2, syntax error, Error Code 126
		if(len != 2)
		{
			addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"126");
			sprintf(message,"The file=%s tag=%d(TeleServiceCode) has a syntax error(length out of(%d,%d)) in the %s group,Error Code(126)\n",fileName,tag,tags[tag].minSize,tags[tag].maxSize,groupString);
			logMessage(message);
			printfInColor(message,1);
		}	
		else 
		{
			//the value is not 0x00,0x10,0x11,0x12,0x20,0x21,0x22,0x60,0x61,0x62,0x63,0x70,0x80,0x90,0x91,0x92 
			//value out of range, Error Code 218
			for(i=0;i<len;i++)
			{
				tempStr[i]=value[i];
			}
			tempStr[i]='\0';
			if(!(strcasecmp(tempStr,"00") == 0 ||
				   strcasecmp(tempStr,"10") == 0 || 
				   strcasecmp(tempStr,"11") == 0 ||
				   strcasecmp(tempStr,"12") == 0 ||
				   strcasecmp(tempStr,"20") == 0 ||
				   strcasecmp(tempStr,"21") == 0 ||
				   strcasecmp(tempStr,"22") == 0 ||
				   strcasecmp(tempStr,"60") == 0 ||
				   strcasecmp(tempStr,"61") == 0 ||
				   strcasecmp(tempStr,"62") == 0 ||
				   strcasecmp(tempStr,"63") == 0 ||
				   strcasecmp(tempStr,"70") == 0 ||
				   strcasecmp(tempStr,"80") == 0 ||
				   strcasecmp(tempStr,"90") == 0 ||
				   strcasecmp(tempStr,"91") == 0 ||
				   strcasecmp(tempStr,"92") == 0))
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"218");
				sprintf(message,"The file=%s tag=%d(TeleServiceCode) has a value out of range error(0x00,0x10,0x11,0x12,0x20,0x21,0x22,0x60,0x61,0x62,0x63,0x70,0x80,0x90,0x91,0x92) in the %s group,Error Code(218)\n",fileName,tag,groupString);
				logMessage(message);
				printfInColor(message,1);
			}	
		}	
	}
	//check the ThirdPartyNumber         
	else if(tag == getTagByName("ThirdPartyNumber"))
	{
		
	}
	//check the UtcTimeOffset          
	else if(tag == getTagByName("UtcTimeOffset"))
	{
		//the length is not 5, syntax error, Error Code 127(MOC/MTC/GPRS) 128(NRTRDE)
		if(len != 5)
		{
			if(groupType == 1)
			{	
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"128");
				sprintf(message,"The file=%s tag=%d(UtcTimeOffset) has a syntax error(length out of(%d,%d)) in the %s group,Error Code(128)\n",fileName,tag,tags[tag].minSize,tags[tag].maxSize,groupString);
			}
			else
			{
				addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"127");
				sprintf(message,"The file=%s tag=%d(UtcTimeOffset) has a syntax error(length out of(%d,%d)) in the %s group,Error Code(127)\n",fileName,tag,tags[tag].minSize,tags[tag].maxSize,groupString);
			}	
			logMessage(message);
			printfInColor(message,1);
		}	
		//the value is not like +0800, value out of range, Error Code 219(MOC/MTC/GPRS) 220(NRTRDE)
		else
		{
			//the value not start with '-' or '+' 
			if(!(value[0] == 0x2B || value[0] == 0x2D))
			{
				if(groupType == 1)
				{
					addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"220");
					sprintf(message,"The file=%s tag=%d(UtcTimeOffset) has a value out of range error in the %s group,Error Code(220)\n",fileName,tag,groupString);
				}	
				else
				{
					addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"219");
					sprintf(message,"The file=%s tag=%d(UtcTimeOffset) has a value out of range error in the %s group,Error Code(219)\n",fileName,tag,groupString);
				}	
				logMessage(message);
				printfInColor(message,1);
				return;
			}
			for(i=1;i<len;i++)
			{
				if(value[i] > 0x39 || value[i] < 0x30)
				{
					if(groupType == 1)
					{
						addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"220");
						sprintf(message,"The file=%s tag=%d(UtcTimeOffset) has a value out of range error in the %s group,Error Code(220)\n",fileName,tag,groupString);
					}	
					else
					{
						addNENodeInDB(senderTadig,fileName,groupType,recordNumber,"219");
						sprintf(message,"The file=%s tag=%d(UtcTimeOffset) has a value out of range error in the %s group,Error Code(219)\n",fileName,tag,groupString);
					}	
					logMessage(message);
					printfInColor(message,1);
					break;
				}	
			}
				
		}	
	}
	
}

