#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "../../snmp/src/include/snmp.h"
#include "../../snmp/src/include/macro.h"

#include "conv_prefix.h"
#include "../../public/src/uwav/numgrp.h"
#include "../../public/src/uwav/number.h"

_conv_prefix	conv_prefix;

#define ASN_1_OCTET_STRING	4
#define ASN_1_INTEGER		1


struct numgrp_table	*xapp_grptab_ptr=NULL;

extern int xap_get_response(u8 oidlen,u32 *oid,u8 *pdata,u8 *vartype);
extern int xap_set_response(u8 oidlen,u32 *oid,u8 *pdata,u16 datalen);

/*------------------------------------------------------------------*/

int	readConvPrefixConf()
{
	char	filename[]="./conf/conv_prefix.conf";
	FILE	*fpConf  = NULL;

	fpConf = fopen(filename,"r");
	if(fpConf == NULL) return 0;
	fread(&conv_prefix,sizeof(_conv_prefix),1,fpConf);
	fclose(fpConf);
/*
	for(i=0;i<MAX_CONV_PREFIX;i++)
	{
		printf("[%03d]:%s,%d,%d,%s,%d\n",
			i,
			conv_prefix.conv_prefix[i].prefix,
			conv_prefix.conv_prefix[i].delete_length,
			conv_prefix.conv_prefix[i].add_length,
			conv_prefix.conv_prefix[i].add_digits,
			conv_prefix.conv_prefix[i].valid_length);
	}
*/
	xappCreateGroupPrefixTable();
	return 1;
}

int	saveConvPrefix()
{
	char	filename[]="./conf/conv_prefix.conf";
	FILE	*fpConf  = NULL;

	fpConf = fopen(filename,"w");
	if(fpConf == NULL) return 0;
	fwrite(&conv_prefix,sizeof(_conv_prefix),1,fpConf);
	fclose(fpConf);
	return 1;
}

int snmpSetConvPrefix(u_char oidlen,DWORD *oid,u_char *pdata,u_short datalen)
{
	DWORD instance;

	if(oidlen<16) return 0;
	instance = oid[15];
	if(instance>=MAX_CONV_PREFIX) return 0;
	if(datalen<19) return 0;

	conv_prefix.conv_prefix[instance].used_flag = 1; 
	memcpy(conv_prefix.conv_prefix[instance].prefix,pdata,16);
	conv_prefix.conv_prefix[instance].delete_length = pdata[16];
	conv_prefix.conv_prefix[instance].add_length = pdata[17];
	memcpy(conv_prefix.conv_prefix[instance].add_digits,&pdata[18],16);
	conv_prefix.conv_prefix[instance].valid_length = pdata[34];
	if(datalen==43)
	{
		memset(conv_prefix.conv_name[instance],0,MAX_NAME_LEN);
		memcpy(conv_prefix.conv_name[instance],&pdata[35],MAX_NAME_LEN);
	}
	if(instance == MAX_CONV_PREFIX-1) saveConvPrefix();
	return datalen;
}

int snmpGetConvPrefix(u_char oidlen,DWORD *oid,u_char *pdata,u_char *vartype)
{
	DWORD instance;
	
	*vartype = 0x04;
	if(oidlen<16) return 0;
	instance = oid[15];
	memcpy(pdata,conv_prefix.conv_prefix[instance].prefix,16);
	pdata[16] = conv_prefix.conv_prefix[instance].delete_length;
	pdata[17] = conv_prefix.conv_prefix[instance].add_length;
	memcpy(&pdata[18],conv_prefix.conv_prefix[instance].add_digits,16);
	pdata[34] = conv_prefix.conv_prefix[instance].valid_length;
	memcpy(&pdata[35],conv_prefix.conv_name[instance],MAX_NAME_LEN);
	return 35+8;
}

int snmpSetCliPrefix(u_char oidlen,DWORD *oid,u_char *pdata,u_short datalen)
{
	DWORD instance;

	if(oidlen<15) return 0;
	instance = oid[14];
	if(instance>=MAX_CLI_PREFIX) return 0;
	if(datalen<19) return 0;

	conv_prefix.cli_prefix[instance].in_property = pdata[0];
	memcpy(conv_prefix.cli_prefix[instance].prefix,&pdata[1],16);
	conv_prefix.cli_prefix[instance].delete_length = pdata[17];
	conv_prefix.cli_prefix[instance].out_property = pdata[18];
	conv_prefix.cli_prefix[instance].add_length = pdata[19];
	memcpy(conv_prefix.cli_prefix[instance].add_digits,&pdata[20],16);
	conv_prefix.cli_prefix[instance].valid_length = pdata[36];
	if(datalen == 45)
	{
		memset(conv_prefix.cli_name[instance],0,MAX_NAME_LEN);
		memcpy(conv_prefix.cli_name[instance],&pdata[37],MAX_NAME_LEN);
	}
	if(instance == MAX_CLI_PREFIX-1) saveConvPrefix();
	return datalen;
}

int snmpGetCliPrefix(u_char oidlen,DWORD *oid,u_char *pdata,u_char *vartype)
{
	DWORD instance;
	
	*vartype = 0x04;
	if(oidlen<15) return 0;
	instance = oid[14];
	if(instance>=MAX_CLI_PREFIX) return 0;
	pdata[0] = conv_prefix.cli_prefix[instance].in_property;
	memcpy(&pdata[1],conv_prefix.cli_prefix[instance].prefix,16);
	pdata[17] = conv_prefix.cli_prefix[instance].delete_length;
	pdata[18] = conv_prefix.cli_prefix[instance].out_property;
	pdata[19] = conv_prefix.cli_prefix[instance].add_length;
	memcpy(&pdata[20],conv_prefix.cli_prefix[instance].add_digits,16);
	pdata[36] = conv_prefix.cli_prefix[instance].valid_length;
	memcpy(&pdata[37],conv_prefix.cli_name[instance],MAX_NAME_LEN);
	return 37+8;
}

int msisdnUnkToInt(char *msisdn_unk, char *msisdn_int)
/* return value: 
	-1 = error length;
	 0 = cannn't find appropriate prefix;
	 1 = conv. succeed
*/
{
	int	retval = 0, index = -1;
	int	loop,len=0,max_len=0,old_len;
	int	delete_len,add_len;

	index = xappSearchGroupTable(msisdn_unk);
	if(index>=0)
	{
		char tmpStart[17],tmpEnd[17];
		
		strcpy(tmpStart,msisdn_unk);
		tmpStart[conv_prefix.group_conv_prefix[index].repStartDigit] = 0;
		
		strcpy(tmpEnd,&msisdn_unk[conv_prefix.group_conv_prefix[index].repEndDigit]);

		sprintf(msisdn_int,"%s%s%s",
				tmpStart,
				conv_prefix.group_conv_prefix[index].repDigitWith,
				tmpEnd);

		return 1;
	}
	for(loop=0;loop<MAX_CONV_PREFIX;loop++)
	{
		if(conv_prefix.conv_prefix[loop].used_flag)
		{
			len = strlen(conv_prefix.conv_prefix[loop].prefix);
			if(len>0)
			{
				if(len>max_len)
				if(strncasecmp(msisdn_unk,
								conv_prefix.conv_prefix[loop].prefix,
								len)==0)
				{
					max_len = len;
					index = loop;
				}//cmp
			}//len>0
		}//used
	}

	if(index>=0 && index<MAX_CONV_PREFIX)
	{
		len = strlen(msisdn_unk);

		if(len>24) len = 24;
		old_len = len;
		
		/*
		len = strlen(msisdn_unk);

		if(len>24) len = 24;
		old_len = len;
		for(loop=len-1;loop>2;loop--)
		{
			if(toupper(msisdn_unk[loop])>'C')
					len --;
			else
					break;
		}
		*/
		if(conv_prefix.conv_prefix[index].valid_length>0)
		{
			if(len != conv_prefix.conv_prefix[index].valid_length)
			{
				strcpy(msisdn_int,msisdn_unk);
				return -1;
			}
		}
		delete_len = conv_prefix.conv_prefix[index].delete_length;
		if(delete_len>len) 
		{
			strcpy(msisdn_int,msisdn_unk);
			return -1;
		}

		add_len	= conv_prefix.conv_prefix[index].add_length;
		if(add_len != strlen(conv_prefix.conv_prefix[index].add_digits))
		{
			strcpy(msisdn_int,msisdn_unk);
			 return -1;
		}
		strcpy(msisdn_int,
				conv_prefix.conv_prefix[index].add_digits);
		strcat(msisdn_int,
				&msisdn_unk[delete_len]);
		msisdn_int[add_len+old_len-delete_len] = 0;
		retval = 1;
	}
	return retval;
}

int	cliUptoCalled(char *caller, char *called)
{
	char	callerBuf[128],tmpBuf[128];//tmpBuf1[128];
	int		loop0=0,loop=0,index=-1,index1=-1;/*1=91 IDD,2=A1 NDD,3=81 UNK*/
	int		len=0,maxlen=0,delete_len=0, add_len=0;
	int		times = 1;
	
	if(called != NULL)
		times = 2;
	
	strcpy(callerBuf,caller);
//	msisdnUnkToInt(callerBuf,caller);
	for(loop0=0;loop0<times;loop0++)
	{
		maxlen = 0;
		if(loop0==1 && index1 == -1)
				return 0;
		
		for(loop=0;loop<MAX_CLI_PREFIX;loop++)
		{
			if(conv_prefix.cli_prefix[loop].in_property == 1)
			{
				sprintf(tmpBuf,"91");
			}else if(conv_prefix.cli_prefix[loop].in_property == 2)
			{
				sprintf(tmpBuf,"a1");
			}else if(conv_prefix.cli_prefix[loop].in_property == 3)
			{
				sprintf(tmpBuf,"81");
			}else 
				continue;
			strcat(tmpBuf,conv_prefix.cli_prefix[loop].prefix);
			len = strlen(tmpBuf);

			if(len>0 && len>maxlen)
			{
				if(loop0==0)
				{
					if(strncasecmp(caller,
								tmpBuf,
								len)==0)
					{
						index1 = loop;
						maxlen = len;
					}//cmp
				}else
				{
					if(strncasecmp(called,
								tmpBuf,
								len)==0)
					{
						index = loop;
						maxlen = len;
					}//cmp
				}
			}//len>0
		}
	}

	if(index1>=0)
	{
		len = strlen(caller);
		delete_len = conv_prefix.cli_prefix[index1].delete_length;
		if(delete_len>len) 
		{
			return -1;
		}
		add_len	= conv_prefix.cli_prefix[index1].add_length;
		if(add_len != strlen(conv_prefix.cli_prefix[index1].add_digits))
		{
			return -1;
		}
		if(conv_prefix.cli_prefix[index1].out_property == 1)
		{	
			sprintf(caller,"91");
		}else if(conv_prefix.cli_prefix[index1].out_property == 2)
		{
			sprintf(caller,"a1");
		}else if(conv_prefix.cli_prefix[index1].out_property == 3)
		{
			sprintf(caller,"81");
		}else 
			sprintf(caller,"81");
		strcat(caller,
			conv_prefix.cli_prefix[index1].add_digits);
		strcat(caller,
			&callerBuf[delete_len+2]);
		len = strlen(callerBuf);
		caller[add_len+len-delete_len] = 0;
	}
	return 1;
}


int snmpSetPlatName(u_char oidlen,DWORD *oid,u_char *pdata,u_short datalen)
{
	DWORD instance;

	if(oidlen<15) return 0;
	instance = oid[14];
	if(instance>=MAX_PLAT_NAME_INSTANCE) return 0;
	if(datalen != MAX_PLAT_NAME_LEN) return 0;
	memcpy(conv_prefix.plat_name[instance],pdata,MAX_PLAT_NAME_LEN);
	if(instance == MAX_PLAT_NAME_INSTANCE-1)
			saveConvPrefix();

	return datalen;
}


int snmpGetPlatName(u_char oidlen,DWORD *oid,u_char *pdata,u_char *vartype)
{
	DWORD instance;
	
	*vartype = 0x04;
	if(oidlen<15) return 0;
	instance = oid[14];
	if(instance>=MAX_PLAT_NAME_INSTANCE) return 0;

	memcpy(pdata,conv_prefix.plat_name[instance],MAX_PLAT_NAME_LEN);
	return MAX_PLAT_NAME_LEN;
}


int snmpSetGroupConvPrefix(u_char oidlen,DWORD *oid,u_char *pdata,u_short datalen)
{
	DWORD instance;
	int		len=0, invalid_flag=0;
	_xapp_group_prefix	tempGroupPrefix;

	if(oidlen<16) return 0;
	instance = oid[15];
	if(instance>=MAX_CONV_PREFIX) return 0;
	if(datalen<50) return 0;
	
	memset(&tempGroupPrefix,0,sizeof(_xapp_group_prefix));

	len = 0;
	memcpy(tempGroupPrefix.startNumber,&pdata[len],MAX_PREFIX_LEN);
	len += MAX_PREFIX_LEN;
	memcpy(tempGroupPrefix.endNumber,&pdata[len],MAX_PREFIX_LEN);
	len += MAX_PREFIX_LEN;
	tempGroupPrefix.repStartDigit = pdata[len];
	len += 1;
	tempGroupPrefix.repEndDigit = pdata[len];
	len += 1;
	memcpy(tempGroupPrefix.repDigitWith,&pdata[len],MAX_PREFIX_LEN);
	//check validity
	if(tempGroupPrefix.repStartDigit>tempGroupPrefix.repEndDigit)
		invalid_flag = 1;
	if(strcmp(tempGroupPrefix.startNumber,tempGroupPrefix.endNumber)>0)
	{
		invalid_flag = 1;
	}
	if(invalid_flag)
	{
		sprintf(pdata,"Error parameter, start>end!");
		return -2;
	}

	memcpy(&conv_prefix.group_conv_prefix[instance],&tempGroupPrefix,sizeof(_xapp_group_prefix));

	if(instance == MAX_CONV_PREFIX-1){
		saveConvPrefix();
		xappCreateGroupPrefixTable();
	}

	return datalen;
}

int snmpGetGroupConvPrefix(u_char oidlen,DWORD *oid,u_char *pdata,u_char *vartype)
{
	DWORD instance;
	int		len = 0;

	*vartype = 0x04;
	if(oidlen<16) return 0;
	instance = oid[15];
	if(instance>=MAX_CONV_PREFIX) return 0;

	memcpy(&pdata[len],conv_prefix.group_conv_prefix[instance].startNumber,MAX_PREFIX_LEN);
	len += MAX_PREFIX_LEN;
	memcpy(&pdata[len],conv_prefix.group_conv_prefix[instance].endNumber,MAX_PREFIX_LEN);
	len += MAX_PREFIX_LEN;
	pdata[len] = conv_prefix.group_conv_prefix[instance].repStartDigit;
	len += 1;
	pdata[len] = conv_prefix.group_conv_prefix[instance].repEndDigit;
	len += 1;
	memcpy(&pdata[len],conv_prefix.group_conv_prefix[instance].repDigitWith,MAX_PREFIX_LEN);
	len += MAX_PREFIX_LEN;
	return len;
}

int xappCreateGroupPrefixTable()
{
	int	i,len;
	struct number_group tmp_num_grp;

	if(xapp_grptab_ptr != NULL)
		delete_numgrp_table(xapp_grptab_ptr);

	xapp_grptab_ptr = assign_numgrp_table("xapp",MAX_CONV_PREFIX);
	for(i=0;i<MAX_CONV_PREFIX;i++)
	{
		len = strlen(conv_prefix.group_conv_prefix[i].startNumber);
		if(len<1 && len>MAX_PREFIX_LEN) 
			continue;
		len = strlen(conv_prefix.group_conv_prefix[i].startNumber);
		tmp_num_grp.start.num_of_digit = len;
		memcpy(tmp_num_grp.start.digit,conv_prefix.group_conv_prefix[i].startNumber,len);
		
		len = strlen(conv_prefix.group_conv_prefix[i].endNumber);
		tmp_num_grp.end.num_of_digit = len;
		memcpy(tmp_num_grp.end.digit,conv_prefix.group_conv_prefix[i].endNumber,len);
		tmp_num_grp.index = i;

		numgrp_insert(xapp_grptab_ptr,
			&tmp_num_grp.start,
			&tmp_num_grp.end,
			tmp_num_grp.index);
	}
}

int	xappSearchGroupTable(char *msisdn_unk)
{
	num16_t num16_tmp;
	int	tmpResult;
	int	len;
	char tmp_number[32];
	
	if(xapp_grptab_ptr==NULL) return -1;

	strcpy(tmp_number,msisdn_unk);
	StringCut(tmp_number,'E');
	len = strlen(tmp_number);

	if(len==0) return -1;
	if(len>MAX_PREFIX_LEN) len = MAX_PREFIX_LEN;
	num16_tmp.num_of_digit = len;
	memcpy(num16_tmp.digit,tmp_number,len);
	if(numgrp_search(&tmpResult,xapp_grptab_ptr,&num16_tmp))
		return tmpResult;
	return -1;

}

/* -----------------------------------------------------------------------------------------*/
/* -- following codes support XAPP mib structrue, refer to XAPP mib definition for detail --*/
/* -- record @2008-10-29																  --*/
/* -----------------------------------------------------------------------------------------*/

/* ---------------------------------------------------------------------------*/
/* ------------------------ function: xap_get_idle_index() -------------------*/
/* -- type1=manipulation prefix, type2=manipulation group, type3=cli prefix --*/
/* -- return =0 ,failed, otherwise succeed -----------------------------------*/
/* ---------------------------------------------------------------------------*/
int xap_get_idle_index(int type, int *newID)
{
	int i;

	switch(type)
	{
		case 1:
			for(i=1;i<MAX_CONV_PREFIX;i++)
			{
				if(	conv_prefix.conv_prefix[i].used_flag == 0)
				{
					*newID = i;
					return 1;
				}
			}
		break;
		case 2:
			for(i=1;i<MAX_CLI_PREFIX;i++)
			{
				if(	strlen(conv_prefix.group_conv_prefix[i].startNumber) == 0)
				{
					*newID = i;
					return 1;
				}
			}
		break;
		case 3:
			for(i=1;i<MAX_CONV_PREFIX;i++)
			{
				if(	strlen(conv_prefix.cli_prefix[i].prefix) == 0)
				{
					*newID = i;
					return 1;
				}
			}
		break;
		default:
		break;
	}
	return 0;
}

/* --------------------- */
/* -- prefix routines -- */
/* --------------------- */

int xap_getnext_manPrefix(DWORD *index_id)
{
	int 		i;

	if(*index_id == 0)
		*index_id = 1;
	for(i = *index_id; i < MAX_CONV_PREFIX; i++)
	{	
		if(	conv_prefix.conv_prefix[i].used_flag)
		{
			*index_id = i;
			return 1;
		}
	}
	*index_id = 0;
	return 0;
}

int xap_get_manPrefix(DWORD column, DWORD *instance, u_char *pdata, u_char *vartype)
{
	int datalen = 0,index;
	
	index = instance[0];
	if(index < 0 || index >= MAX_CONV_PREFIX 
		|| conv_prefix.conv_prefix[index].used_flag == FALSE)
		return -1;
	
	*vartype = ASN_1_OCTET_STRING;
	switch(column)
	{
		case 1: /* index */
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = index;
			break;
		case 2: /* title */
			datalen = strlen(conv_prefix.conv_name[index]);
			memcpy(pdata,conv_prefix.conv_name[index],datalen);
		break;
		case 3: /* prefix */
			datalen = strlen(conv_prefix.conv_prefix[index].prefix);
			memcpy(pdata,conv_prefix.conv_prefix[index].prefix,datalen);
			break;
		case 4: /* delete count */
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = conv_prefix.conv_prefix[index].delete_length;
		break;
		case 5:/* insert count	*/
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = conv_prefix.conv_prefix[index].add_length;
		break;
		case 6: /* insert digits */
			datalen = strlen(conv_prefix.conv_prefix[index].add_digits);
			memcpy(pdata,conv_prefix.conv_prefix[index].add_digits,datalen);
		break;
		case 7: /* number length */
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = conv_prefix.conv_prefix[index].valid_length;
		break;
		case 8: /* status */
			*vartype = ASN_1_INTEGER;
			pdata[0] = 1; /* active */	
			datalen = 1;
		break;
		default:
			return -1;
		break;			
	}
	return datalen;
}

int xap_set_manPrefix(DWORD column, DWORD *instance, u_char *pdata, unsigned short datalen)
{
	int	index;
	int	newId;
		
	if(datalen == 0)
		return -1;

	index = instance[0];
	if(index < 0 || index >= MAX_CONV_PREFIX)
		return -1;
	
	switch(column)
	{
		case 1:/* create	*/
			if(xap_get_idle_index(1, &newId))
			{
				conv_prefix.conv_prefix[index].used_flag = TRUE;
				return newId;
			}
			else
				return -1;
		break;
		case 2: /* title */
			if(datalen>=MAX_NAME_LEN)
				return -1;
			memset(conv_prefix.conv_name[index], 0, MAX_NAME_LEN);
			memcpy(conv_prefix.conv_name[index], pdata, datalen);
			break;
		case 3: /* prefix */
			if(datalen>=MAX_PREFIX_LEN)
				return -1;
			memset(conv_prefix.conv_prefix[index].prefix, 0, MAX_PREFIX_LEN);
			memcpy(conv_prefix.conv_prefix[index].prefix, pdata, datalen);
			break;
		case 4: /* delete count */
			if(pdata[0]>=MAX_PREFIX_LEN)
				return -1;
			conv_prefix.conv_prefix[index].delete_length = pdata[0];
			break;
		case 5: /* insert count	*/
			if(pdata[0]>=MAX_PREFIX_LEN)
				return -1;
			conv_prefix.conv_prefix[index].add_length = pdata[0];
			break;
		case 6: /* insert digits */
			if(datalen>=MAX_PREFIX_LEN)
				return -1;
			memset(conv_prefix.conv_prefix[index].add_digits, 0, MAX_PREFIX_LEN);
			memcpy(conv_prefix.conv_prefix[index].add_digits, pdata, datalen);			
			break;
		case 7: /* number length */
			if(pdata[0]>=MAX_PREFIX_LEN)
				return -1;
			conv_prefix.conv_prefix[index].valid_length = pdata[0];
			break;
		case 8:  /* status */
			if(pdata[0] == 6) /* 6==delete */
			{
				memset(&conv_prefix.conv_prefix[index],0,sizeof(_conv_prefix_record));			
			    memset(conv_prefix.conv_name[index], 0, MAX_NAME_LEN);
			}
		break;	
		default:
			return -1;
		break;
	}
	return datalen;
}

/*------------------*/
/*-- group routines --*/
/*------------------*/

int xap_getnext_groupPrefix(DWORD *index_id)
{
	int 		i;

	if(*index_id == 0)
		*index_id = 1;
	
	for(i = *index_id; i < MAX_CONV_PREFIX; i++)
	{	
		if(	strlen(conv_prefix.group_conv_prefix[i].startNumber))
		{
			*index_id = i;
			return 1;
		}
	}
	*index_id = 0;
	return 0;
}

int xap_get_groupPrefix(DWORD column, DWORD *instance, u_char *pdata, u_char *vartype)
{
	int datalen = 0,index;
	
	index = instance[0];
	if(index < 0 || index >= MAX_CONV_PREFIX 
		|| strlen(conv_prefix.group_conv_prefix[index].startNumber) == 0)
		return -1;
	
	*vartype = ASN_1_OCTET_STRING;
	switch(column)
	{
		case 1: /* index */
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = index;
			break;
		case 2: /* title, this define inhert...not reasonable */
			datalen = strlen(conv_prefix.plat_name[index]);
			memcpy(pdata,conv_prefix.plat_name[index],datalen);
		break;
		case 3: /* start number */
			datalen = strlen(conv_prefix.group_conv_prefix[index].startNumber);
			memcpy(pdata,conv_prefix.group_conv_prefix[index].startNumber,datalen);
			break;
		case 4: /* end number */
			datalen = strlen(conv_prefix.group_conv_prefix[index].endNumber);
			memcpy(pdata,conv_prefix.group_conv_prefix[index].endNumber,datalen);
		break;
		case 5:/*  replace digit start	*/
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = conv_prefix.group_conv_prefix[index].repStartDigit;
		break;
		case 6: /* replace digit end */
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = conv_prefix.group_conv_prefix[index].repEndDigit;
		break;
		case 7: /* replace digit with */
			datalen = strlen(conv_prefix.group_conv_prefix[index].repDigitWith);
			memcpy(pdata,conv_prefix.group_conv_prefix[index].repDigitWith,datalen);
		break;
		case 8: /* lock flag */
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = conv_prefix.group_conv_prefix[index].status;
		break;
		case 9: /* status */
			*vartype = ASN_1_INTEGER;
			pdata[0] = 1; /* active */	
			datalen = 1;
		break;
		default:
			return -1;
		break;			
	}
	return datalen;
}

int xap_set_groupPrefix(DWORD column, DWORD *instance, u_char *pdata, unsigned short datalen)
{
	int	index;
	int	newId;
		
	if(datalen == 0)
		return -1;

	index = instance[0];
	if(index < 0 || index >= MAX_CONV_PREFIX)
		return -1;
	
	switch(column)
	{
		case 1:/* create	*/
			if(xap_get_idle_index(2, &newId))
			{
				return newId;
			}
			else
				return -1;
		break;
		case 2: /* title */
			if(datalen>=MAX_NAME_LEN)
				return -1;
			memset(conv_prefix.plat_name[index], 0, MAX_NAME_LEN);
			memcpy(conv_prefix.plat_name[index], pdata, datalen);
			break;
		case 3: /* start number */
			if(datalen>MAX_PREFIX_LEN) return -1;
			memset(conv_prefix.group_conv_prefix[index].startNumber, 0, MAX_PREFIX_LEN+1);
			memcpy(conv_prefix.group_conv_prefix[index].startNumber,pdata,datalen);
			break;
		case 4: /* end number */
			if(datalen>MAX_PREFIX_LEN) return -1;
			memset(conv_prefix.group_conv_prefix[index].endNumber, 0, MAX_PREFIX_LEN+1);
			memcpy(conv_prefix.group_conv_prefix[index].endNumber,pdata,datalen);
		break;
		case 5:/*  replace digit start	*/
			if(datalen>=MAX_PREFIX_LEN) return -1;
			conv_prefix.group_conv_prefix[index].repStartDigit = pdata[0];
		break;
		case 6: /* replace digit end */
			if(datalen>=MAX_PREFIX_LEN) return -1;
			conv_prefix.group_conv_prefix[index].repEndDigit = pdata[0];
		break;
		case 7: /* replace digit with */
			if(datalen>MAX_PREFIX_LEN) return -1;
			memset(conv_prefix.group_conv_prefix[index].repDigitWith, 0, MAX_PREFIX_LEN+1);
			memcpy(conv_prefix.group_conv_prefix[index].repDigitWith,pdata,datalen);			
		break;
		case 8: /* lock flag */ /* here, create table should be more technical, but... */
			conv_prefix.group_conv_prefix[index].status = pdata[0] ;
			xappCreateGroupPrefixTable();
		break;
		case 9:  /* status */
			if(pdata[0] == 6) /* 6==delete */
			{
				memset(&conv_prefix.group_conv_prefix[index],0,sizeof(_xapp_group_prefix));			
			    memset(conv_prefix.plat_name[index], 0, MAX_NAME_LEN);
				xappCreateGroupPrefixTable();
			}
		break;	
		default:
			return -1;
		break;
	}
	return datalen;
}

/*------------------*/
/*-- cli routines --*/
/*------------------*/

int xap_getnext_cliPrefix(DWORD *index_id)
{
		int 		i;

	if(*index_id == 0)
		*index_id = 1;
	for(i = *index_id; i < MAX_CLI_PREFIX; i++)
	{	
		if(	strlen(conv_prefix.cli_prefix[i].prefix))
		{
			*index_id = i;
			return 1;
		}
	}
	*index_id = 0;
	return 0;
}

int xap_get_cliPrefix(DWORD column, DWORD *instance, u_char *pdata, u_char *vartype)
{
	int datalen = 0,index;
	
	index = instance[0];
	if(index < 0 || index >= MAX_CLI_PREFIX 
		|| strlen(conv_prefix.cli_prefix[index].prefix) == 0)
		return -1;
	
	*vartype = ASN_1_OCTET_STRING;
	switch(column)
	{
		case 1: /* index */
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = index;
			break;
		case 2: /* title */
			datalen = strlen(conv_prefix.cli_name[index]);
			memcpy(pdata,conv_prefix.cli_name[index],datalen);
		break;
		case 3: /* o nai */
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = conv_prefix.cli_prefix[index].in_property;
		break;
		case 4: /* prefix */
			datalen = strlen(conv_prefix.cli_prefix[index].prefix);
			memcpy(pdata,conv_prefix.cli_prefix[index].prefix,datalen);
			break;
		case 5: /* delete count */
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = conv_prefix.cli_prefix[index].delete_length;
		break;
		case 6:
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = conv_prefix.cli_prefix[index].out_property;
		break;
		case 7:/* add count	*/
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = conv_prefix.cli_prefix[index].add_length;
		break;
		case 8: /* insert digits */
			datalen = strlen(conv_prefix.cli_prefix[index].add_digits);
			memcpy(pdata,conv_prefix.cli_prefix[index].add_digits,datalen);
		break;
		case 9: /* number length */
			*vartype = ASN_1_INTEGER;
			datalen = 1;
			pdata[0] = conv_prefix.cli_prefix[index].valid_length;
		break;
		case 10: /* status */
			*vartype = ASN_1_INTEGER;
			pdata[0] = 1; /* active */	
			datalen = 1;
		break;
		default:
			return -1;
		break;			
	}
	return datalen;
}

int xap_set_cliPrefix(DWORD column, DWORD *instance, u_char *pdata, unsigned short datalen)
{
	int	index;
	int	newId;
		
	if(datalen == 0)
		return -1;

	index = instance[0];
	if(index < 0 || index >= MAX_CLI_PREFIX)
		return -1;
	
	switch(column)
	{
		case 1:/* create	*/
			if(xap_get_idle_index(3, &newId))
			{
				return newId;
			}
			else
				return -1;
		break;
		case 2: /* title */
			if(datalen>=MAX_NAME_LEN)
				return -1;
			memset(conv_prefix.cli_name[index], 0, MAX_NAME_LEN);
			memcpy(conv_prefix.cli_name[index], pdata, datalen);
			break;
		case 3: /* in nai */
			conv_prefix.cli_prefix[index].in_property = pdata[0] ;
			break;
		case 4: /* prefix */
			if(datalen>=MAX_PREFIX_LEN)
				return -1;
			memset(conv_prefix.cli_prefix[index].prefix, 0, MAX_PREFIX_LEN);
			memcpy(conv_prefix.cli_prefix[index].prefix, pdata, datalen);
			break;
		case 5: /* delete count */
			if(pdata[0]>=MAX_PREFIX_LEN)
				return -1;
			conv_prefix.cli_prefix[index].delete_length = pdata[0];
			break;
		case 6: /* out nai */
			conv_prefix.cli_prefix[index].out_property = pdata[0] ;
			break;
		case 7: /* insert count	*/
			if(pdata[0]>=MAX_PREFIX_LEN)
				return -1;
			conv_prefix.cli_prefix[index].add_length = pdata[0];
			break;
		case 8: /* insert digits */
			if(datalen>=MAX_PREFIX_LEN)
				return -1;
			memset(conv_prefix.cli_prefix[index].add_digits, 0, MAX_PREFIX_LEN);
			memcpy(conv_prefix.cli_prefix[index].add_digits, pdata, datalen);			
			break;
		case 9: /* number length */
			if(pdata[0]>=MAX_PREFIX_LEN)
				return -1;
			conv_prefix.cli_prefix[index].valid_length = pdata[0];
			break;
		case 10:  /* status */
			if(pdata[0] == 6) /* 6==delete */
			{
				memset(&conv_prefix.cli_prefix[index],0,sizeof(_cli_prefix));			
			    memset(conv_prefix.cli_name[index], 0, MAX_NAME_LEN);
			}
		break;	
		default:
			return -1;
		break;
	}
	return datalen;
}


static struct snmp_table_profile xapp_tables[] = {
	{
		.name = "xappManPrefix",
		.index.len = 11+2,
		.index.oid = {1,3,6,1,4,1,1373,2,3,2,5,2,2},
		.column = {1, 2, 3, 4, 5, 6, 7, 8, 0},
		.level = 1,
		.get_instance = xap_getnext_manPrefix,
		.get_resp = xap_get_manPrefix,
		.set_resp = xap_set_manPrefix
	},
	{
		.name = "xappManGroup",
		.index.len = 11+2,
		.index.oid = {1,3,6,1,4,1,1373,2,3,2,5,2,3},
		.column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
		.level = 1,
		.get_instance = xap_getnext_groupPrefix,
		.get_resp = xap_get_groupPrefix,
		.set_resp = xap_set_groupPrefix
	},
	{
		.name = "xappCliPrefix",
		.index.len = 11+2,
		.index.oid = {1,3,6,1,4,1,1373,2,3,2,5,2,4},
		.column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0},
		.level = 1,
		.get_instance = xap_getnext_cliPrefix,
		.get_resp = xap_get_cliPrefix,
		.set_resp = xap_set_cliPrefix
	}	
};

static struct snmp_register xapp_register = {
	.name = "XAPP",
	.prefix_len = 11,
	.prefix_oid = {1,3,6,1,4,1,1373,2,3,2,5},
	.num_of_table = 3,
	.table = xapp_tables,
	.default_get_resp = (getcall)xap_get_response,
	.default_set_resp = (setcall)xap_set_response
};

void xap_snmp_registration(void)
{	
	register_snmp_table(&xapp_register);
}
