
/*********************************************************/
/*Title:  sccpmib.c                                      */
/*Descr:  SCCP Management information Base Interface     */
/*Author: Liang Hanxi                                    */
/*Create: 2002-4-16                                      */
/*Modify:                                                */

/*********************************************************/

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

/*===========import================*/
extern int BuildRouteIndex (  );        //gtt.c
extern int sccp_loadparam (  ); //sccpparam.c
extern void sccp_saveparam (  );
extern int sccp_setparam ( DWORD * oid, BYTE * pdata, WORD datalen );
extern int sccp_getparam ( DWORD * oid, BYTE * pdata, BYTE * vartype );
extern void sccp_reset (  );    //sccp.c
extern void DWORD2BYTE ( BYTE * pdword, BYTE * pbyte, int len );        //sccpfun.c
extern void spLogDebug ( DWORD mask, const char *fmt, ... );

/*===========export================*/
void sccpmib_init (  );
void sccp_sethb (  );

/*===========private===============*/
int sccp_setmib ( BYTE oidlen, DWORD * oid, BYTE * pdata, WORD datalen );
int sccp_getmib ( BYTE oidlen, DWORD * oid, BYTE * pdata, BYTE * vartype );
void sccp_snmp_registration(void);
int set_localnode_title(void);
void sccp_trapcallback ( BYTE oidlen, DWORD * oid, BYTE * pdata, WORD len, snmp_addr * addr );

static BYTE sccpSaveFlag=0;

int checkSccpSaveFlag()
{
	return sccpSaveFlag;
}

void sccpEnableSaveFlag()
{
	sccpSaveFlag = 1;
}

void sccpDisableSaveFlag()
{
	sccpSaveFlag = 0;
}

void sccpmib_init (  )
{
//    DWORD oid[20] = SCCP_OID;

//    inquire_setmsg ( SCCP_OIDLEN, oid, sccp_setmib );
//    inquire_getmsg ( SCCP_OIDLEN, oid, sccp_getmib );
	set_localnode_title();
	sccp_snmp_registration();
    inquire_trapmsg ( sccp_trapcallback );
}

void sccp_sethb (  )
{
    set_status ( 2, 4 + SCCP_Param.RegNum, SCCP_Param.version );
    set_led ( 4, 9 );
}

/************************************************/
//MIB Interface=================================>

/************************************************/
int sccp_setmib ( BYTE oidlen, DWORD * oid, BYTE * pdata, WORD datalen )
{

	sccpEnableSaveFlag();
    switch ( oid[SCCP_OIDLEN] )
    {
    case 1:                    //CSTA, read only
        return -1;
    case 2:                    //Paramter
        return sccp_setparam ( &oid[SCCP_OIDLEN + 1], pdata, datalen );
    case 3:                    //Status
        switch ( oid[SCCP_OIDLEN + 1] )
        {
        case 1:                //version, read only
            return -1;
        case 2:                //command
            switch ( pdata[0] )
            {
            case 0:            //reset
                spLogDebug ( SCCPDB_SNMP, "Reset SCCP..." );
		sccp_saveparam (  );		
                sccp_reset (  );
                break;
            case 1:            //load
                return -1;
            case 2:            //save
                spLogDebug ( SCCPDB_SNMP, "Save Parameter..." );
                sccp_saveparam (  );
                break;
            }
            return 1;
        case 3:                //status, read only
            return -1;
        }
        break;
    }
    return -1;
}

int sccp_getmib ( BYTE oidlen, DWORD * oid, BYTE * pdata, BYTE * vartype )
{
    DWORD instance;
    SCCP_CSTA *pcsta;

    spLogDebug ( SCCPDB_SNMP, "get sccp mib..." );
    switch ( oid[SCCP_OIDLEN] )
    {
    case 1:                    //CSTA          
        instance = oid[SCCP_OIDLEN + 1];
        if( instance == SccpCstaInd || instance > 95 )
        {
            *vartype = NosuchInstance;
            spLogDebug ( SCCPDB_SNMP, "csta message not ready. instance=%d", instance );
            return 0;
        }
        pcsta = &SccpCsta[instance];
        if( pcsta->timestamp == 0 )
        {
            spLogDebug ( SCCPDB_SNMP, "csta message is expired" );
            *vartype = 5;
            return 0;
        }
        *vartype = 4;
        spLogDebug ( SCCPDB_SNMP, "Respond csta message" );
        DWORD2BYTE ( ( BYTE * ) & pcsta->timestamp, pdata, sizeof ( SCCP_CSTA ) );
        return sizeof ( SCCP_CSTA );
    case 2:                    //Config
        return sccp_getparam ( &oid[SCCP_OIDLEN + 1], pdata, vartype );
    case 3:                    //Status
        switch ( oid[SCCP_OIDLEN + 1] )
        {
        case 1:                //version
            spLogDebug ( SCCPDB_SNMP, "Get SCCP Version" );
            memcpy ( pdata, SCCP_Param.version, 3 );
            *vartype = 4;
            return 3;
        case 2:                //command, write only
            return -1;
        case 3:                //status
            pdata[0] = SCCP_Param.status;
            *vartype = 2;
            return 1;
        }
        break;
    }
    return -1;
}

//#define OMC_HB_OID     {1,3,6,1,4,1,1373,1,4,1,1}
#define OMC_HB_OID     {1,3,6,1,4,1,1373,2,4,1}
#define OMC_HB_OIDLEN  10
int AddToIpList ( DWORD ip, BYTE ssn );

void sccp_OMCIP_detect ( DWORD ip )
{
    int i;
    BYTE index = 0;

    for ( i = 0; i <= 1; i++ )
    {
        if( SCCP_Param.OMCIP[i] == ip )
            return;
        else if( SCCP_Param.OMCIP[i] == 0 )
            index = i;
    }
    SCCP_Param.OMCIP[index] = ip;
    AddToIpList ( ip, 4 );
}

extern ull SCCPSerialNumber;

void sccp_trapcallback ( BYTE oidlen, DWORD * oid, BYTE * pdata, WORD len, snmp_addr * addr )
{
    DWORD ObjID[20] = FLATFORM_HB_OID;
    BYTE ssn;
    short infolen, i, pos = 2;  //component_id=0:iptrans
    heartbeat_msg *phbmsg = ( heartbeat_msg * ) pdata;
    BYTE *pstatus = phbmsg->info;
    DWORD OMCHLObjID[20] = OMC_HB_OID;
    BYTE newHeartbeat = 0;

    if( memcmp ( &oid[7], &OMCHLObjID[7], ( OMC_HB_OIDLEN - 7 ) * 4 ) == 0 )    //omc heartbeat
    {                           //automatic add omc ip into ip list,
        //if receive omc heartbeat and the omc serial number is equial to the local serial number,
        //then the platform will send heartbeat if received omc heartbeat
        if( ( SCCPSerialNumber == 0 ) ||        //support old version, do not have serial number
            ( Bcd2Ull ( &pdata[39], SCCP_SERNUM_LEN ) == SCCPSerialNumber ) )
            sccp_OMCIP_detect ( addr->remote_ip );
    }

    if( memcmp ( &oid[9], &ObjID[9], ( FLATFORM_HB_OIDLEN - 9 ) * 4 ) != 0 || addr->remote_ip == SCCP_Param.ip )
        return;

    if( sizeof ( struct heartbeat_msg ) > ( INFO_LEN + 18 ) )
        newHeartbeat = 1;

    if( !newHeartbeat )
    {                           //old version heartbeat, length and component_id are one octet
        pos = 1;
        pos += pstatus[pos] + 1;        //length of iptrans status
        pos++;                  //component_id=1:mtp3
        pos += pstatus[pos] + 1;        //length of mtp3
        pos++;                  //component_id=2:sccp
    }
    else
    {                           //new version heartbeat, length and component_id are 2 octets
        pos++;                  //length is 2 octets
        pos += pstatus[pos] + 1;        //length of iptrans     status  
        pos++;                  //component_id=1:mtp3
        pos++;                  //component_id is 2 octets

     //   pos++;                  //length is 2 octets
       // pos += pstatus[pos] + 1;        //length of mtp3
	 pos += pstatus[pos]*256 + pstatus[pos+1] + 2; //mtp3 length is more than 255

        pos++;                  //component_id=2:sccp
        pos++;                  //component_id is 2 octets

        pos++;                  //sccp length 1
    }
    infolen = pstatus[pos++];

    if( infolen <= 4 || infolen > 32 )
        return;

    for ( i = pos + 4; i < pos + infolen; i++ )
    {
        ssn = pstatus[i];
        //      printf("beat recieve,ssn=%d\n",ssn);
        if( ssn <= 1 )
            continue;
        if( addr->remote_ip == LocalSSN[ssn].ip[0] )
        {
            LocalSSN[ssn].status[0] = ST_Enable;
            LocalSSN[ssn].timeout[0] = T_hbrecv;
        }
        else if( addr->remote_ip == LocalSSN[ssn].ip[1] )
        {
            LocalSSN[ssn].status[1] = ST_Enable;
            LocalSSN[ssn].timeout[1] = T_hbrecv;
        }
    }

}


int sccp_get_sysparam(u32 column, u32 *instance, u8 *pdata, u8 *vartype)
{
	int datalen=-1;
	char ver[32]={0};
	
	switch(column) 
	{
		case 1:
			sprintf(ver, "%02d.%02d.%02d", SCCP_Param.version[0], SCCP_Param.version[1], SCCP_Param.version[2]);
			GET_OCTETSTRING(ver, strlen(ver));
			break;
		case 2: //command
			GET_U8(0);
			break;
		default:
			break;
	}
	return datalen;
}

int sccp_set_sysparam(u32 column, u32 *instance, u8 *pdata, u16 datalen)
{
	u8 command=0;
	
	switch(column) 
	{
		case 1:	//version
			break;
		case 2:	//command
			SET_U8(command);
			if(command==1)
			{
				spLogDebug ( SCCPDB_SNMP, "Reset SCCP..." );
                		sccp_reset (  );
			}      
			else if(command ==2)
			{
			
		                spLogDebug ( SCCPDB_SNMP, "Save Parameter..." );
               			sccp_saveparam (  );				
			}
			break;	
		default:			
			break;
	}
	sccpEnableSaveFlag();
	return datalen;
}

int sccp_getnext_localNode(u32 *instance)
{
	static u8 ssn=0;

	for(ssn=instance[0]; ssn<=254;ssn++)
	{
		switch(ssn)
		{
			case 4:
			case 6:
			case 7:
			case 8:
			case 9:
			case 10:
			case 11:
			case 19:
			case 20:
			case 21:
			case 22:
			case 23:
			case 24:
			case 25:
			case 32:
			case 33:
			case 34:
			case 142:
			case 146:
			case 147:
			case 153:
			case 254:
				instance[0]=ssn;
				return 1;
			default:
				break;			
			}
		}
	return 0;
}

int set_localnode_title(void)
{
	LOCAL_SSN *ptr=NULL;

	ptr	= &LocalSSN[4];
	strcpy((char *)ptr->title, "OMC");
	ptr	= &LocalSSN[6];
	strcpy((char *)ptr->title, "HLR");
	ptr	= &LocalSSN[7];
	strcpy((char *)ptr->title, "VLR");
	ptr	= &LocalSSN[8];
	strcpy((char *)ptr->title, "MSC");
	ptr	= &LocalSSN[9];
	strcpy((char *)ptr->title, "EIR");
	ptr	= &LocalSSN[10];
	strcpy((char *)ptr->title, "AUC");
	ptr	= &LocalSSN[11];
	strcpy((char *)ptr->title, "SMSC");
	ptr	= &LocalSSN[19];
	strcpy((char *)ptr->title, "SMPP-EMSE");
	ptr	= &LocalSSN[20];
	strcpy((char *)ptr->title, "SMPP-SMSC");
	ptr	= &LocalSSN[21];
	strcpy((char *)ptr->title, "SMPP-OMC");
	ptr	= &LocalSSN[22];
	strcpy((char *)ptr->title, "SRF-0");
	ptr	= &LocalSSN[23];
	strcpy((char *)ptr->title, "SRF-1");
	ptr	= &LocalSSN[24];
	strcpy((char *)ptr->title, "SRF-2");
	ptr	= &LocalSSN[25];
	strcpy((char *)ptr->title, "SRF-3");
	ptr	= &LocalSSN[32];
	strcpy((char *)ptr->title, "NPLR");
	ptr	= &LocalSSN[33];
	strcpy((char *)ptr->title, "OPPS");
	ptr	= &LocalSSN[34];
	strcpy((char *)ptr->title, "MNP");
	ptr	= &LocalSSN[146];
	strcpy((char *)ptr->title, "SSF");
	ptr	= &LocalSSN[147];
	strcpy((char *)ptr->title, "SCF-CAP");
	ptr	= &LocalSSN[153];
	strcpy((char *)ptr->title, "SCF-MAP");
	ptr	= &LocalSSN[254];
	strcpy((char *)ptr->title, "AIF");
	return  1;
}

int sccp_get_localNode(u32 column, u32 *instance, u8 *pdata, u8 *vartype)
{
	int datalen = -1;
	LOCAL_SSN *ptr=NULL;
	char	msisdn_str[32]={0};

	if (instance[0] >= 256)	
		return -1;
	  ptr	= &LocalSSN[instance[0]];

	switch(column)
	{
		case 1:	//index
			GET_INTEGER(instance[0]);
			break;	
		case 2:	//title
			GET_STRING((char *)ptr->title);
			break;	
		case 3:	//
			GET_U8(ptr->NetID);
			break;
		case 4:	//
			Bcd2Str(msisdn_str, ptr->msisdn, ptr->msisdn_len);
			if(msisdn_str[ptr->msisdn_len*2-1]=='F' ||msisdn_str[ptr->msisdn_len*2-1]=='f')
				GET_OCTETSTRING(msisdn_str, ptr->msisdn_len*2-1);
			else
				GET_OCTETSTRING(msisdn_str, ptr->msisdn_len*2);
			break;
		case 5:
			GET_IP(&ptr->ip[0]);
			break;
		case 6:
			GET_IP(&ptr->ip[1]);
			break;
		case 7:
			GET_INTEGER(ptr->acn_index);	
			break;	
		case 8:
			GET_U8(0);
			break;
		default:
			break;
	}
	return datalen;
}

int sccp_set_localNode(u32 column, u32 *instance, u8 *pdata, u16 datalen)
{
	LOCAL_SSN *ptr=NULL;
	char	msisdn_str[32] = {0};
	LOCAL_SSN *pLocalSSN;
	LOCAL_SSN OldLocalSSN;
	
	if (instance[0] >= 256)	
		return -1;

        pLocalSSN = &LocalSSN[instance[0]];

        /* copy the old important parameter */
        OldLocalSSN.NetID = pLocalSSN->NetID;
        OldLocalSSN.ip[0] = pLocalSSN->ip[0];
        OldLocalSSN.ip[1] = pLocalSSN->ip[1];
        /* copy the old important parameter */
	
	ptr = &LocalSSN[instance[0]];
	switch(column)
	{
		case 3:	//
			SET_U8(ptr->NetID);
			break;
		case 4:	//
			if(datalen >=16)
				return -2;
			SET_OCTETSTRING(msisdn_str, datalen);
			Str2Bcd(ptr->msisdn, msisdn_str, MAX_DIGITS);
			ptr->msisdn_len = (datalen+1)/2;
			break;
		case 5:
			SET_IP(&ptr->ip[0]);
			break;
		case 6:
			SET_IP(&ptr->ip[1]);
			break;
		case 7:
			SET_INTEGER(ptr->acn_index);	
			if(ptr->acn_index >=SCCP_ROUTE_NUM)
				ptr->acn_index = 0;
			break;
		case 8:
			break;
		default:
			break;
	}

        /* if old and new important parameter are same then return */
        if( OldLocalSSN.NetID == pLocalSSN->NetID && OldLocalSSN.ip[0] == pLocalSSN->ip[0] && OldLocalSSN.ip[1] == pLocalSSN->ip[1] )
            return datalen;
        /* if old and new important parameter are same then return */

        LocalSSN[instance[0]].local = 0;
        LocalSSN[instance[0]].status[0] = LocalSSN[instance[0]].status[1] = 0;
        if( LocalSSN[instance[0]].ip[0] > 0 && LocalSSN[instance[0]].ip[0] != 0xFFFFFFFF )
        {
            if( LocalSSN[instance[0]].ip[0] == SCCP_Param.ip )
            {
                LocalSSN[instance[0]].status[0] = 1;
                LocalSSN[instance[0]].local = 1;
            }
            else
            {
                LocalSSN[instance[0]].status[0] = 3;
                LocalSSN[instance[0]].timeout[0] = T_hbrecv;
            }
        }
        if( LocalSSN[instance[0]].ip[1] > 0 && LocalSSN[instance[0]].ip[1] != 0xFFFFFFFF )
        {
            if( LocalSSN[instance[0]].ip[1] == SCCP_Param.ip )
            {
                LocalSSN[instance[0]].status[1] = 1;
                LocalSSN[instance[0]].local = 2;
            }
            else
            {
                LocalSSN[instance[0]].status[1] = 3;
                LocalSSN[instance[0]].timeout[1] = T_hbrecv;
            }
        }

        SCCP_Param.T_reset = 100;	

	sccpEnableSaveFlag();
	return datalen;
}


int sccp_getnext_gtt(u32 *instance)
{
	int i;
	SCCP_ROUTE *pRoute=NULL;

        pRoute = &RouteList[instance[0]];

	for(i=instance[0];i<SCCP_ROUTE_NUM;i++)
	{
	        pRoute = &RouteList[i];
		if(pRoute->avail==0 && (pRoute->StartDigits[0]&0xf0)==0xf0)
			continue;
		instance[0] = i;
		return 1;		
	}
	return 0;
}


int sccp_get_gtt(u32 column, u32 *instance, u8 *pdata, u8 *vartype)
{
	int datalen = -1;
	SCCP_ROUTE *ptr=NULL;
	u32 dpc;
	char	msisdn_str[32]={0};
	
	if (instance[0] >= SCCP_ROUTE_NUM)	
		return -1;
        ptr = &RouteList[instance[0]];

	switch(column)
	{
		case 1:	//index
			GET_INTEGER(instance[0]);
			break;	
		case 2:	//admin
			GET_U8(ptr->avail);
			break;	
		case 3:	//
			GET_U8(ptr->NP);
			break;
		case 4:	//
			GET_U8(ptr->TT);
			break;
		case 5:
			Bcd2Str(msisdn_str, ptr->StartDigits, ptr->len);
			GET_OCTETSTRING(msisdn_str, BcdLen ( ptr->StartDigits, MAX_DIGITS ));
			break;
		case 6:
			Bcd2Str(msisdn_str, ptr->EndDigits, ptr->len);
			GET_OCTETSTRING(msisdn_str, BcdLen ( ptr->EndDigits, MAX_DIGITS ));
			break;
		case 7:
			GET_U8(ptr->NetID);			
			break;
		case 8:
			dpc = ptr->DPC[2]+ptr->DPC[1]*0x100+ptr->DPC[0]*0x10000;
			GET_INTEGER(dpc);			
			break;
		case 9:
			GET_U8(ptr->SSN);			
			break;
		case 10:
			GET_U8(ptr->RI);			
			break;	
		case 11:
			GET_U8(ptr->AI);			
			break;
		case 12:
			GET_U8(ptr->ReplaceStart);			
			break;			
		case 13:
			GET_U8(ptr->ReplaceEnd);			
			break;
		case 14:
			GET_U8(ptr->OutNP);			
			break;
		case 15:
			Bcd2Str(msisdn_str, ptr->ReplaceDigits, ptr->replace_len);
			GET_OCTETSTRING(msisdn_str, BcdLen ( ptr->ReplaceDigits, MAX_DIGITS ));
			break;
		case 16:
			GET_INTEGER(ptr->acn_index);	
			break;
		case 17:
			GET_U8(1);
			break;
		default:
			break;
	}
	return datalen;
}

int sccp_set_gtt(u32 column, u32 *instance, u8 *pdata, u16 datalen)
{
	SCCP_ROUTE *ptr=NULL;
	u32 DPC=0;
	u8 tmp=0;
	int new_id=0;
	char	msisdn_str[32] = {0};


	if(column == Create_Object_Cloumn)
	{
		SET_INTEGER(new_id);
		if(new_id >=SCCP_ROUTE_NUM)
			strcpy((char*)pdata,"MAX ROUTE is 1023.");
		ptr = &RouteList[new_id];
		if(ptr->avail ==1)
		{
			strcpy((char*)pdata,"ROUTE is unlocked.");
			return -2;
		}
		ptr->avail = 1;
		sccpEnableSaveFlag();
		return datalen;
	}
        spLogDebug ( SCCPDB_SNMP, "Set GTT Table.instance=%d", instance[0] );
        if( instance[0] >= SCCP_ROUTE_NUM )
            return -1;
     ptr = &RouteList[instance[0]];

        SCCP_Param.T_reset = 100;       //2s
	switch(column)
	{
		case 2:	//admin
			SET_U8(ptr->avail);
			break;	
		case 3:	//
			SET_U8(ptr->NP);
			break;
		case 4:	//
			SET_U8(ptr->TT);
			break;
		case 5:
			if(datalen >=16)
				return -2;
			SET_OCTETSTRING(msisdn_str, datalen);
			Str2Bcd(ptr->StartDigits, msisdn_str, MAX_DIGITS);
		        ptr->len = ( BcdLen ( ptr->StartDigits, MAX_DIGITS ) + 1 ) / 2;
			break;
		case 6:
			if(datalen >=16)
				return -2;
			SET_OCTETSTRING(msisdn_str, datalen);
			Str2Bcd(ptr->EndDigits, msisdn_str, MAX_DIGITS);	
			break;
		case 7:
			SET_U8(ptr->NetID);			
			break;
		case 8:
			SET_INTEGER(DPC);
			ptr->DPC[2] = DPC&0xff;
			ptr->DPC[1] = (DPC>>8)&0xff;
			ptr->DPC[0] = (DPC>>16)&0xff;
			break;
		case 9:
			SET_U8(ptr->SSN);			
			break;
		case 10:
			SET_U8(ptr->RI);			
			break;	
		case 11:
			SET_U8(ptr->AI);			
			break;
		case 12:
			SET_U8(ptr->ReplaceStart);			
			break;			
		case 13:
			SET_U8(ptr->ReplaceEnd);			
			break;
		case 14:
			SET_U8(ptr->OutNP);			
			break;
		case 15:
			if(datalen >=16)
				return -2;
			SET_OCTETSTRING(msisdn_str, datalen);
			Str2Bcd(ptr->ReplaceDigits, msisdn_str, MAX_DIGITS);
			ptr->replace_len = ( BcdLen ( ptr->ReplaceDigits, MAX_DIGITS ) + 1 ) / 2;
			break;
		case 16:
			SET_INTEGER(ptr->acn_index);
			if(ptr->acn_index >=SCCP_ROUTE_NUM)
				ptr->acn_index = 0;
			break;
		case 17:
			SET_U8(tmp);
			if(tmp==6)
			{
				memset(ptr, 0, sizeof(SCCP_ROUTE));
				memset(ptr->StartDigits, 0xff, MAX_DIGITS*2);
				}
			break;
		default:
			break;
	}
        if( ptr->ReplaceStart >= 1 && ptr->ReplaceStart <= ptr->ReplaceEnd )
        	ptr->convert = 1;
        else
            ptr->convert = 0;	
		sccpEnableSaveFlag();
	return datalen;
}

int sccp_getnext_acn(u32 *instance)
{
	int i;
	SCCP_ACN_VER_TABLE *pACN=NULL;

        pACN = &acn_ver_table[instance[0]];

	for(i=instance[0];i<SCCP_ROUTE_NUM;i++)
	{
	        pACN = &acn_ver_table[i];
		if(pACN->avail==0 && pACN->LocationUpdating ==0)
			continue;
		instance[0] = i;
		return 1;		
	}
	return 0;
}

int sccp_get_acn(u32 column, u32 *instance, u8 *pdata, u8 *vartype)
{
	int datalen = -1;
	SCCP_ACN_VER_TABLE *ptr=NULL;
	
	if (instance[0] >= SCCP_ROUTE_NUM)	
		return -1;
        ptr = &acn_ver_table[instance[0]];
		
	switch(column)
	{
		case 1:	//index
			GET_INTEGER(instance[0]);
			break;	
		case 2:	//admin
			GET_U8(ptr->avail);
			break;	
		case 3:	//
			GET_U8(ptr->LocationUpdating);
			break;
		case 4:	//
			GET_U8(ptr->LocationCancellation);
			break;
		case 5:
			GET_U8(ptr->RoamingNumberEnquiry);			
			break;
		case 6:
			GET_U8(ptr->LocationInfoRetrieval);			
			break;
		case 7:
			GET_U8(ptr->ResetContext);			
			break;	
		case 8:
			GET_U8(ptr->HandoverControl);			
			break;
		case 9:
			GET_U8(ptr->EquipmentManagement);			
			break;			
		case 10:
			GET_U8(ptr->InfoRetrieval);			
			break;
		case 11:
			GET_U8(ptr->InterVLRInfoRetrieval);			
			break;
		case 12:
			GET_U8(ptr->SubscriberDataManagement);	
			break;
		case 13:
			GET_U8(ptr->Tracing);	
			break;
		case 14:
			GET_U8(ptr->NetworkFunctionalSS);	
			break;
		case 15:
			GET_U8(ptr->NetworkUnstructuredSS);	
			break;
		case 16:
			GET_U8(ptr->ShortMessageGateway);	
			break;
		case 17:
			GET_U8(ptr->MOShortMessageRelay);	
			break;
		case 18:
			GET_U8(ptr->ShortMessageAlert);	
			break;
		case 19:
			GET_U8(ptr->ShortMessageWDM);	
			break;
		case 20:
			GET_U8(ptr->MTShortMessageRelay);	
			break;
		case 21:
			GET_U8(ptr->IMSIRetrieval);	
			break;
		case 22:
			GET_U8(ptr->MSPurging);	
			break;
		case 23:
			GET_U8(ptr->SubscriberInfoEnquiry);	
			break;
		case 24:
			GET_U8(ptr->AnyTimeInfoEnquiry);	
			break;
		case 25:
			GET_U8(ptr->CallControlTransfer);	
			break;
		case 26:
			GET_U8(ptr->SSInvocationNotification);	
			break;
		case 27:
			GET_U8(ptr->GroupCallControl);	
			break;
		case 28:
			GET_U8(ptr->GPRSLocationUpdating);	
			break;
		case 29:
			GET_U8(ptr->GPRSLocationInfoRetrieval);	
			break;
		case 30:
			GET_U8(ptr->FailureReporting);	
			break;
		case 31:
			GET_U8(ptr->GPRSNotifying);	
			break;
		case 32:
			GET_U8(ptr->Reporting);	
			break;
		case 33:
			GET_U8(ptr->CallCompletion);	
			break;
		case 34:
			GET_U8(ptr->InternalSIWFSAllocation);	
			break;
		case 35:
			GET_U8(ptr->InternalSecurityTriplets);	
			break;
		case 36:
			GET_U8(ptr->InternalSubscriberInterrogating);	
			break;
		case 37:
			GET_U8(ptr->InternalHLRSubscriberManagement);	
			break;
		case 38:
			GET_U8(ptr->InternalHLRPingAUC);	
			break;
		case 39:
			GET_U8(ptr->VLRCamelPhase);
			break;
		case 40:
			GET_U8(1);
			break;
		default:
			break;
	}
	return datalen;

}

struct _SCCP_ACN_VER_TABLE acn_ver_def=
{
	.avail = 0,
	.LocationUpdating = 3,
	.LocationCancellation = 3, 
	.RoamingNumberEnquiry =3,
	.LocationInfoRetrieval = 3,
	.ResetContext = 2,
	.HandoverControl = 2,
	.EquipmentManagement = 2,
	.InfoRetrieval = 2,
	.InterVLRInfoRetrieval = 2,
	.SubscriberDataManagement = 3,
	.Tracing = 3,
	.NetworkFunctionalSS = 2,
	.NetworkUnstructuredSS = 2,
	.ShortMessageGateway = 2,
	.MOShortMessageRelay = 2,
	.ShortMessageAlert = 2,
	.ShortMessageWDM = 2,//waiting Data Management 
	.MTShortMessageRelay = 2,
	.IMSIRetrieval = 2,
	.MSPurging = 3,
	.SubscriberInfoEnquiry = 3,
	.AnyTimeInfoEnquiry = 3,
	.CallControlTransfer = 3,
	.SSInvocationNotification = 3,
	.GroupCallControl = 3,
	.GPRSLocationUpdating = 3,
	.GPRSLocationInfoRetrieval = 3,
	.FailureReporting = 3,
	.GPRSNotifying = 3,
	.Reporting = 3,
	.CallCompletion = 3,
	.InternalSIWFSAllocation = 3,
	.InternalSecurityTriplets = 2,
	.InternalSubscriberInterrogating = 2,
	.InternalHLRSubscriberManagement = 2,
	.InternalHLRPingAUC = 2,
	.VLRCamelPhase = 7
};

int sccp_set_acn(u32 column, u32 *instance, u8 *pdata, u16 datalen)
{
	SCCP_ACN_VER_TABLE *ptr=NULL;
	u8 tmp=0;
	int new_id=0;

	if(column == Create_Object_Cloumn)
	{
		SET_INTEGER(new_id);
		if(new_id >=SCCP_ROUTE_NUM)
			strcpy((char*)pdata,"MAX ACN is 1023.");
		ptr = &acn_ver_table[new_id];
		if(ptr->avail ==1)
		{
			strcpy((char*)pdata,"ACN is unlocked.");
			return -2;
		}
		memcpy(ptr, &acn_ver_def, sizeof(SCCP_ACN_VER_TABLE));
		ptr->avail = 1;
		sccpEnableSaveFlag();
		return datalen;
	}
        spLogDebug ( SCCPDB_SNMP, "Set ACN Table.instance=%d", instance[0] );
        if( instance[0] >= SCCP_ROUTE_NUM )
            return -1;
     ptr = &acn_ver_table[instance[0]];

        SCCP_Param.T_reset = 100;       //2s
	switch(column)
	{
		case 2:	//admin
			SET_U8(ptr->avail);
			break;	
		case 3:	//
			SET_U8(ptr->LocationUpdating);
			break;
		case 4:	//
			SET_U8(ptr->LocationCancellation);
			break;
		case 5:
			SET_U8(ptr->RoamingNumberEnquiry);			
			break;
		case 6:
			SET_U8(ptr->LocationInfoRetrieval);			
			break;
		case 7:
			SET_U8(ptr->ResetContext);			
			break;	
		case 8:
			SET_U8(ptr->HandoverControl);			
			break;
		case 9:
			SET_U8(ptr->EquipmentManagement);			
			break;			
		case 10:
			SET_U8(ptr->InfoRetrieval);			
			break;
		case 11:
			SET_U8(ptr->InterVLRInfoRetrieval);			
			break;
		case 12:
			SET_U8(ptr->SubscriberDataManagement);	
			break;
		case 13:
			SET_U8(ptr->Tracing);	
			break;
		case 14:
			SET_U8(ptr->NetworkFunctionalSS);	
			break;
		case 15:
			SET_U8(ptr->NetworkUnstructuredSS);	
			break;
		case 16:
			SET_U8(ptr->ShortMessageGateway);	
			break;
		case 17:
			SET_U8(ptr->MOShortMessageRelay);	
			break;
		case 18:
			SET_U8(ptr->ShortMessageAlert);	
			break;
		case 19:
			SET_U8(ptr->ShortMessageWDM);	
			break;
		case 20:
			SET_U8(ptr->MTShortMessageRelay);	
			break;
		case 21:
			SET_U8(ptr->IMSIRetrieval);	
			break;
		case 22:
			SET_U8(ptr->MSPurging);	
			break;
		case 23:
			SET_U8(ptr->SubscriberInfoEnquiry);	
			break;
		case 24:
			SET_U8(ptr->AnyTimeInfoEnquiry);	
			break;
		case 25:
			SET_U8(ptr->CallControlTransfer);	
			break;
		case 26:
			SET_U8(ptr->SSInvocationNotification);	
			break;
		case 27:
			SET_U8(ptr->GroupCallControl);	
			break;
		case 28:
			SET_U8(ptr->GPRSLocationUpdating);	
			break;
		case 29:
			SET_U8(ptr->GPRSLocationInfoRetrieval);	
			break;
		case 30:
			SET_U8(ptr->FailureReporting);	
			break;
		case 31:
			SET_U8(ptr->GPRSNotifying);	
			break;
		case 32:
			SET_U8(ptr->Reporting);	
			break;
		case 33:
			SET_U8(ptr->CallCompletion);	
			break;
		case 34:
			SET_U8(ptr->InternalSIWFSAllocation);	
			break;
		case 35:
			SET_U8(ptr->InternalSecurityTriplets);	
			break;
		case 36:
			SET_U8(ptr->InternalSubscriberInterrogating);	
			break;
		case 37:
			SET_U8(ptr->InternalHLRSubscriberManagement);	
			break;
		case 38:
			SET_U8(ptr->InternalHLRPingAUC);	
			break;
		case 39:
			SET_U8(ptr->VLRCamelPhase);
			break;
		case 40:
			SET_U8(tmp);
			if(tmp==6)
			{
				memset(ptr, 0, sizeof(SCCP_ACN_VER_TABLE));
			}
			break;
		default:
			break;
	}

	sccpEnableSaveFlag();
	return datalen;
}

int move_acn_from_mtp3(u8 NetID, DWORD spc)
{
	int i,index=0;
	u8 *pAcnInfo=NULL;
    pAcnInfo = spc_to_acn ( NetID, spc );
    if( pAcnInfo == NULL )
        return 0;    
	for(i = 0; i < SCCP_ROUTE_NUM;  i++)
	{
		if(acn_ver_table[i].avail == 0)
			continue;
		if(memcmp(pAcnInfo, &acn_ver_table[i].LocationUpdating, 36)==0)//check acn table
		{
			index = i;
			printf( "already has acn info in the table index=%d\r\n", index );			
			return index;
		}
	}

	for(i = 0; i < SCCP_ROUTE_NUM;  i++)// create an acn 
	{
		if(acn_ver_table[i].avail == 1)
			continue;
		memcpy(&acn_ver_table[i].LocationUpdating, pAcnInfo, 36);
		acn_ver_table[i].avail = 1;
		index = i;
		printf( "create acn info in the table index=%d\r\n", index );			
		return index;
	}
	
    return index;
}


//MTP3 OID Prefix: {1,3,6,1,4,1,1373,2,3,2,2}
static struct snmp_table_profile sccp_tables[] = {
	/****** Parameter table ******/
	{
		.name = "system",
		.index.len = 13,
		.index.oid = {1,3,6,1,4,1,1373,2,3,2,3,2,1},
		.column = {0,1,2,3},
		.level = 0,
		.get_instance = NULL,
		.get_resp = sccp_get_sysparam,
		.set_resp = sccp_set_sysparam
	},
	{
		.name = "local node",
		.index.len = 14,
		.index.oid = {1,3,6,1,4,1,1373,2,3,2,3,2,2,1},
		.column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0},
		.level = 1,
		.get_instance = sccp_getnext_localNode,
		.get_resp = sccp_get_localNode,
		.set_resp = sccp_set_localNode
	},
	{
		.name = "gtt table",
		.index.len = 14,
		.index.oid = {1,3,6,1,4,1,1373,2,3,2,3,2,3,1},
		.column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0},
		.level = 1,
		.get_instance = sccp_getnext_gtt,
		.get_resp = sccp_get_gtt,
		.set_resp = sccp_set_gtt
	},
	{
		.name = "acn version table",
		.index.len = 14,
		.index.oid = {1,3,6,1,4,1,1373,2,3,2,3,2,4,1},
		.column = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,\
		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 0},
		.level = 1,
		.get_instance = sccp_getnext_acn,
		.get_resp = sccp_get_acn,
		.set_resp = sccp_set_acn
	}
		
};

static struct snmp_register sccp_register = {
	.name = "SCCP",
	.prefix_len = 11,
	.prefix_oid = {1, 3, 6, 1, 4, 1, 1373, 2, 3, 2, 3},
	.num_of_table = sizeof(sccp_tables)/sizeof(struct snmp_table_profile),
	.table = sccp_tables,
	.default_get_resp = sccp_getmib,
	.default_set_resp = sccp_setmib
};

void sccp_snmp_registration(void)
{
	register_snmp_table(&sccp_register);
}

