/*	XAP provider monitor c file			*/
/*	Written by Liu Zhiguo 2003-03-13	*/
/*	Version 1.0							*/
/*	--------------------------------	*/

#include "xap_provider.h"
#include "capp/cap_head.h"
#include "../../snmp/src/include/snmp.h"
#include "../../snmp/src/include/macro.h"
#include "conv_prefix.h"

#define	XAP_MAX_PAGE			8
#define	XAP_MAX_LINE			22
#define	XAP_STATE_LINE			20
#define	XAP_MODULE_ID			4
#define	XAP_ID_LEN				15
#define	XAP_TITLE_LEN			16
#define	XAP_LINE_LEN			17
#define	XAP_PAGE_POINT			14
#define	XAP_LINE_POINT			15

#define	XAP_CONF_FILE			"conf/xap_sysparam.conf"
#define	XAP_MSCID_CONF_FILE		"conf/xap_mscid.conf"

#define	XAP_PREOBJ_LEN			11
extern void xap_snmp_registration();
extern int xap_roaming_rules_init();
void xap_disp_page(u8 page);
void xap_init();
int	readConvPrefixConf();
void xap_check_save_param();
extern u8 init_mappconst();
extern u8 init_cappconst();
extern int	xap_save_roaming_rule();
extern int xap_roaming_rule_test(char *vlr_number);

static u8	xap_status = 1;
static u8	*xap_disp_ptr;
static u32	xap_page;
static u8	xap_did[2],xap_next_did[2];
static u8	xap_ver[] = {1,0,01};
u32	xap_object_id[] = {1,3,6,1,4,1,1373,2,3,2,5};
static u32	xap_status_id[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,XAP_MODULE_ID + 2,1};
static u32	xap_version_id[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,XAP_MODULE_ID + 2,2};
static u32	xap_ascin_id[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,XAP_MODULE_ID + 2,3};
static u32	xap_ascout_id[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,XAP_MODULE_ID + 2,4};
static u32	xap_page_title[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,XAP_MODULE_ID + 2,5,1};
static u32	xap_page_line[] = {1,3,6,1,4,1,1373,1,3,2,3,1,2,XAP_MODULE_ID + 2,5,2,2};

static char		opr_type_desc[5][16] = {"??", "Req", "Ind", "Rsp", "Cnf"};

static unsigned char xap_save_conv_param_flag = 0, 
				 xap_save_roaming_rule_flag = 0,	
				 xap_save_system_param_flag=0;	

char	map_pabort_desc[7][32] = {
	"Undefined", 
	"ProviderMalfunction", 
	"SupportingReleased",
	"ResourceLimitation",
	"MaintenanceActivity",
	"VersionIncompatibility",
	"AbnormalMAPDialogue"};
char	map_uabort_desc[10][32] = {
	"Undefined", 
	"ShortTermProblem",
	"LongTermProblem",
	"HandoverCancel",
	"RadioChannelRelease",
	"NetworkPathRelease",
	"CallRelease",
	"AssociateProcedureFailure",
	"TandemDialogueRelease",
	"RemoteOperationFailure"};

char	tcap_pabort_desc[7][64] = {
	"unrecognized message tyep",
	"unrecognized transaction ID",
	"badly formatted transaction portion",
	"incorrect transaction portion",
	"resource limitation",
	"abnormal dialogue",
	"no common dialogue"};

char	tcap_uabort_desc[3][32] = {
	"no given reason", 
	"specific reason",
	"ACN not supplied"};

u8 xap_get_addstr(char *str,u8 *bcd,u8 bcd_len)
{   // transfer bcd code to string
    u8  ii;

    BcdToAscii(str,bcd,bcd_len*2);
    for (ii = 0;ii < bcd_len*2;ii ++)
    {
        if (str[ii] == 'e' || str[ii] == 'E')
            break;
    }
    str[ii] = '\0';
    return ii;
}
/* str size >64 */
void xap_get_opstr(int flag , int op, char *str)
{
	 if( flag == MAP_FLAG )
	 {
		 switch(op)
		 {
		 	  case UpLoc :
		 	  	strcpy(str , "MAP_UPDATE_LOCATION");
		 	  	break;
		 	  case CancelLoc:
		 	  	strcpy(str , "MAP_CANCEL_LOCATION");
					break;
				case PurgeMS:
		 	  	strcpy(str , "MAP_PURGE_MS");
					break;
				case SndIdent:
		 	  	strcpy(str , "MAP_SEND_IDENTIFICATION"); 
					break;
				case PreHo:
		 	  	strcpy(str , "MAP_PREPARE_HANDOVER");
					break;						
				case SndEndSig:
		 	  	strcpy(str , "MAP_SEND_END_SIGNAL");
					break;					
				case ProcAccSig:
		 	  	strcpy(str , "MAP_PROCESS_ACCESS_SIGNALLING"); 
					break;				
				case FwdAccSig:
		 	  	strcpy(str , "MAP_FORWARD_ACCESS_SIGNALLING");
					break;					
				case PreSubsHo:
		 	  	strcpy(str , "MAP_PREPARE_SUBSEQUENT_HANDOVER");
					break;					
				case SndAuthInfo:
		 	  	strcpy(str , "MAP_SEND_AUTHENTICATION_INFO");
					break;				
				case ChkIMEI:
		 	  	strcpy(str , "MAP_CHECK_IMEI");
					break;					
				case InsSubData:
		 	  	strcpy(str , "MAP_INSERT_SUBSCRIBER_DATA");
					break;			
				case DelSubData:
		 	  	strcpy(str , "MAP_DELETE_SUBSCRIBER_DATA");
					break;						
				case Reset:
		 	  	strcpy(str , "MAP_RESET");
					break;					
				case FwdChkSSInd:
		 	  	strcpy(str , "MAP_FORWARD_CHECK_SS_INDICATION");
					break;				
				case RestoreData:
		 	  	strcpy(str , "MAP_RESTORE_DATA");
					break;				
				case ActvTraceMode:
		 	  	strcpy(str , "MAP_ACTIVATE_TRACE_MODE");
					break;				
				case DeactvTraceMode:
		 	  	strcpy(str , "MAP_DEACTIVATE_TRACE_MODE");
					break;				
				case SndIMSI:
		 	  	strcpy(str , "MAP_SEND_IMSI");
					break;						
				case SndRoutInfo:
		 	  	strcpy(str , "MAP_SEND_ROUTING_INFORMATION");
					break;					
				case ProvRoamNum:
		 	  	strcpy(str , "MAP_PROVIDE_ROAMING_NUMBER");
					break;					
				case ResumeCH	:
		 	  	strcpy(str , "MAP_RESUME_CALL_HANDLING");
					break;				
				case ProvSIWFSNum	:
		 	  	strcpy(str , "MAP_Provide_SIWFS_Number");
					break;			
				case SIWFSSigMdf	:
		 	  	strcpy(str , "MAP_SIWFS_Signalling_Modify");
					break;				
				case SetRepState	:
		 	  	strcpy(str , "MAP_SET_REPORTING_STATE");
					break;			
				case StatusRep	:
		 	  	strcpy(str , "MAP_STATUS_REPORT");
					break;				
				case RmtUserFree	:
		 	  	strcpy(str , "MAP_REMOTE_USER_FREE");
					break;				
				case RegSS	:
		 	  	strcpy(str , "MAP_REGISTER_SS");
					break;				
				case EraseSS	:
		 	  	strcpy(str , "MAP_ERASE_SS");
					break;				
				case ActvSS		:
		 	  	strcpy(str , "MAP_ACTIVATE_SS");
					break;			
				case DeactvSS	:
		 	  	strcpy(str , "MAP_DEACTIVATE_SS");
					break;			
				case InterSS	:
		 	  	strcpy(str , "MAP_INTERROGATE_SS");
					break;						
				case UnstrctSSReq		:
		 	  	strcpy(str , "MAP_UNSTRUCTURED_SS_REQUEST");
					break;		
				case UnstrctSSNoti	:
		 	  	strcpy(str , "MAP_UNSTRUCTURED_SS_NOTIFY");
					break;			
				case RegPasswd	:
		 	  	strcpy(str , "MAP_REGISTER_PASSWORD");
					break;				
				case GetPasswd	:
		 	  	strcpy(str , "MAP_GET_PASSWORD");
					break;				
				case RegCCEntry		:
		 	  	strcpy(str , "MAP_REGISTER_CC_ENTRY");
					break;			
				case EraseCCEntry		:
		 	  	strcpy(str , "MAP_ERASE_CC_ENTRY");
					break;		
				case SndRoutInfoForSM	:
		 	  	strcpy(str , "MAP_SEND_ROUTING_INFO_FOR_SM");
					break;		
				case FwdSM	:
		 	  	strcpy(str , "MAP_FORWARD_SHORT_MESSAGE");
					break;					
				//case MOFwdSM	:
		 	  //	strcpy(str , "MAP_MO_FORWARD_SHORT_MESSAGE");
				//	break;				
				//case MTFwdSM	:
		 	  //	strcpy(str , "MAP_MT_FORWARD_SHORT_MESSAGE");
				//	break;					
				case MTFwdSM_v3		:
		 	  	strcpy(str , "MAP_MT_FORWARD_SHORT_MESSAGE");
					break;			
				case RptSMDelvStat:
		 	  	strcpy(str , "MAP_REPORT_SM_DELIVERY_STATUS");
					break;				
				case InfSC		:
		 	  	strcpy(str , "MAP_INFORM_SERVICE_CENTRE");
					break;			
				case AlrtSC		:
		 	  	strcpy(str , "MAP_ALERT_SERVICE_CENTRE");
					break;				
				case RdyForSM		:
		 	  	strcpy(str , "MAP_READY_FOR_SM");
					break;			
				case ProvSubInfo:
		 	  	strcpy(str , "MAP_PROVIDE_SUBSCRIBER_LOCATION");
					break;					
				case AnyTimeInter:
		 	  	strcpy(str , "MAP_ANY_TIME_INTERROGATION");
					break;				
				case SSInvNoti:
		 	  	strcpy(str , "MAP_SS_INVOCATION_NOTIFY");
					break;				
				case PreGrpCall	:
		 	  	strcpy(str , "MAP_PREPARE_GROUP_CALL");
					break;				
				case SndGrpCallEndSig	:
		 	  	strcpy(str , "MAP_send group call end signal");
					break;		
				case ProcGrpCallSig	:
		 	  	strcpy(str , "MAP_process group call signalling");
					break;			
				case FwdGrpCallSig	:
		 	  	strcpy(str , "forward group call signalling");
					break;			
				case UpGprsLoc:
		 	  	strcpy(str , "MAP_update GPRS location");
					break;					
				case SndRoutInfoForGprs	:
		 	  	strcpy(str , "MAP_SEND_ROUTING_INFO_FOR_GPRS");
					break;		
				case FailRep	:
		 	  	strcpy(str , "MAP_FAIL_REPORT");
					break;					
				case NoteMsPresForGprs	:
		 	  	strcpy(str , "MAP_NOTE_MS_PRESENT_FOR_GPRS");
					break;		
				case SendParam	:
		 	  	strcpy(str , "MAP_SEND_PARAMETERS"); 
					break;				
				case NoteSubPrnt:
		 	  	strcpy(str , "MAP_NOTE_SUBSCRIBER_PRESENT");
					break;					
				case ProcUnstrctSSData	:
		 	  	strcpy(str , "MAP_PROCESS_UNSTRUCTURED_SS_REQUEST");
					break;	
				case BeginSubAct:
		 	  	strcpy(str , "MAP_BEGIN_SUBSRIBER_ACTIVITY");
					break;					
				case PerformHo:
		 	  	strcpy(str , "MAP_PERFORM_HANDOVER");
					break;					
				case PerformSubsHo:
		 	  	strcpy(str , "MAP_PERFORM_SUBSCRIBERS_HANDOVER");
					break;				
				case NoteInterHo	:
		 	  	strcpy(str , "MAP_NOTE_INTER_HANDOVER");
					break;						
				case AlrtSCWithoutRes	:
		 	  	strcpy(str , "MAP_ALERT_SERVICE_CENTRE_WITHOUT_RESULT");
					break;		
				case TraceSubAct	:
		 	  	strcpy(str , "MAP_TRACE_SUBSRCIBER_ACTIVITY");
					break;				
				case SecuTrip	:				
		 	  	strcpy(str , "MAPH_ SECURITY_TRIPLETS");
					break;
				case InterrSubs:
		 	  	strcpy(str , "MAPH_INTERROGATE_SUBSCRIBER");
					break;
				case CreateSubs:				
		 	  	strcpy(str , "MAPH_CREATE_SUBSCRIBER");
					break;
				case DelSubs:						
		 	  	strcpy(str , "MAPH_DELETER_SUBSCRIBER");
					break;
				case PingAuc	:		
		 	  	strcpy(str , "MAPH_HLR_PING_AUC");
					break;
				default :
					strcpy(str,"MAP_OP_UNKNOWN");
					break;
		 }
	 }
	 else if( flag == CAP_FLAG )
	 {
	 	 
		 switch(op)
		 {
		 	  case CAP_OC_InitialDP:
		 	    strcpy(str , "CAP_InitialDP");
		 	  	break;
		 	  case CAP_OC_AssistRequestInstructions:
		 	    strcpy(str , "CAP_AssistRequestInstructions");
		 	  	break;
		 	  case CAP_OC_EstablishTemporaryConnection:
		 	  	strcpy(str , "CAP_EstablishTemporaryConnection");
		 	  	break;
		 	  case CAP_OC_DisconnectForwardConnection:	
		 	  	strcpy(str , "CAP_DisconnectForwardConnection");
		 	  	break;
		 	  case CAP_OC_ConnectToResource:
		 	  	strcpy(str , "CAP_ConnectToResource");
		 	  	break;
		 	  case CAP_OC_Connect:
		 	  	strcpy(str , "CAP_Connect");
		 	  	break;
		 	  case CAP_OC_ReleaseCall:
		 	  	strcpy(str , "CAP_ReleaseCall");
		 	  	break;
		 	  case CAP_OC_RequestReportBCSMEvent:
		 	  	strcpy(str , "CAP_RequestReportBCSMEvent");
		 	  	break;
		 	  case CAP_OC_EventReportBCSM:
		 	  	strcpy(str , "CAP_EventReportBCSM");
		 	  	break;
		 	  case CAP_OC_Continue:
		 	  	strcpy(str , "CAP_Continue");
		 	  	break;
		 	  case CAP_OC_ResetTimer:
		 	  	strcpy(str , "CAP_ResetTimer");
		 	  	break;
		 	  case CAP_OC_FurnishChargingInformation:
		 	  	strcpy(str , "CAP_FurnishChargingInformation");
		 	  	break;
		 	  case CAP_OC_ApplyCharging:
		 	  	strcpy(str , "CAP_ApplyCharging");
		 	  	break;
		 	  case CAP_OC_ApplyChargingReport:
		 	  	strcpy(str , "CAP_ApplyChargingReport");
		 	  	break;
		 	  case CAP_OC_CallInformationReport:
		 	  	strcpy(str , "CAP_CallInformationReport");
		 	  	break;
		 	  case CAP_OC_CallInformationRequest:
		 	  	strcpy(str , "CAP_CallInformationRequest");
		 	  	break;
		 	  case CAP_OC_SendChargingInformation:
		 	  	strcpy(str , "CAP_SendChargingInformation");
		 	  	break;
		 	  case CAP_OC_PlayAnnouncement:
		 	  	strcpy(str , "CAP_PlayAnnouncement");
		 	  	break;
		 	  case CAP_OC_PromptAndCollectUserInformation:
		 	  	strcpy(str , "CAP_PromptAndCollectUserInformation");
		 	  	break;
		 	  case CAP_OC_SpecializedResourceReport:
		 	  	strcpy(str , "CAP_SpecializedResourceReport");
		 	  	break;
		 	  case CAP_OC_Cancel:		
		 	  	strcpy(str , "CAP_Cancel");
		 	  	break;				
		 	  case CAP_OC_ActivityTest:			
		 	  	strcpy(str , "MCAP_OC_ActivityTest");
		 	  	break;		
		 	  case CAP_OC_ApplyWarningTone:		
		 	  	strcpy(str , "CAP_ApplyWarningTone");
		 	  	break;		
		 	  case CAP_OC_CCF_Continue:				 
		 	  	strcpy(str , "CAP_CCF_Continue");
		 	  	break;	
		 	  case CAP_OC_InitialDPSMS:		
		 	  	strcpy(str , "CAP_InitialDPSMS");
		 	  	break;			
		 	  case CAP_OC_FurnishChargingInformationSMS:
		 	  	strcpy(str , "CAP_FurnishChargingInformationSMS");
		 	  	break;
		 	  case CAP_OC_ConnectSMS:					
		 	  	strcpy(str , "MCAP_OC_ConnectSMS");
		 	  	break;
		 	  case CAP_OC_RequestReportSMSEvent:	
		 	  	strcpy(str , "CAP_RequestReportSMSEvent");
		 	  	break;	
		 	  case CAP_OC_EventReportSMS:	
		 	  	strcpy(str , "CAP_EventReportSMS");
		 	  	break;			
		 	  case CAP_OC_ContinueSMS:	
		 	  	strcpy(str , "CAP_ContinueSMS");
		 	  	break;				
		 	  case CAP_OC_ReleaseSMS:		
		 	  	strcpy(str , "CAP_ReleaseSMS");
		 	  	break;			
		 	  case CAP_OC_ResetTimerSMS:
		 	  	strcpy(str , "CAP_ResetTimerSMS");
		 	  	break;
		 	  default :
					strcpy(str,"CAP_OP_UNKNOWN");
					break;
		 	  	
		 }
	 }
	 
	 
}

void xap_read_conf(void)
{
	FILE		*fp;
	struct		stat fileinfo;

	xap_inter_ptr->local_prefix[0] = 0xEE;
	xap_inter_ptr->local_prefix[1] = 0xEE;
	fp = fopen(XAP_CONF_FILE,"rb");
	if (fp == NULL)
	{
		printf("can not open file %s!!\n",XAP_CONF_FILE);
		return;
	}
	fread(xap_inter_ptr->mcc,20,1,fp);

	stat(XAP_CONF_FILE,&fileinfo);
	if (fileinfo.st_size != 20)
	{//old version, mdc is 1 octet long
		xap_inter_ptr->mnc[0] = xap_inter_ptr->mnc0;
		xap_inter_ptr->mnc[1] = 0xee;
	}
       if(xap_inter_ptr->establishment_timer<DLGPEND_TIME)
       	xap_inter_ptr->establishment_timer = DLGPEND_TIME;
       
	fclose(fp);
}

void xap_read_mscid_conf(void)
{
	FILE		*fp;

	fp = fopen(XAP_MSCID_CONF_FILE,"rb");
	if (fp == NULL)
	{
		printf("can not open file %s!!\n",XAP_MSCID_CONF_FILE);
		return;
	}
	fread(xap_inter_ptr->mscidToNum,3072,1,fp);

	fclose(fp);
}

void xap_write_conf(void)
{
	FILE		*fp;

	fp = fopen(XAP_CONF_FILE,"wb");
	if (fp == NULL)
	{
		printf("can not open file %s!!\n",XAP_CONF_FILE);
		return;
	}
	fwrite(xap_inter_ptr->mcc,20,1,fp);
	fclose(fp);
}

void xap_write_mscid_conf(void)
{
	FILE		*fp;
	
	fp = fopen(XAP_MSCID_CONF_FILE,"wb");
	if (fp == NULL)
	{
		printf("can not open file %s!!\n",XAP_MSCID_CONF_FILE);
		return;
	}
	fwrite(xap_inter_ptr->mscidToNum,3072,1,fp);
	fclose(fp);	
}



#ifdef DEBUG_TEST
void xap_send_ascout(char *asc_str)
{
	StrTrimLeftSpace(asc_str);
	if( asc_str[0] == CNULL )
	{
		return;
	}
	//printf("[XAPP]: %s",asc_str); 
}
#else
void xap_send_ascout(char *asc_str)
{
	if (xap_vm_ptr->debug_data.send_control == 1)
		return;
	if ((strlen(asc_str) + strlen((char *)xap_vm_ptr->debug_data.ascout_buf)) > XAP_ASCOUT_LEN/4)	// buffer is full
	{
		xap_vm_ptr->debug_data.send_control = 1;
//		strcat(xap_vm_ptr->debug_data.ascout_buf,"\r\n--\r\n");
//		strcpy(xap_vm_ptr->debug_data.ascout_buf,asc_str);
	}
	else
		strcat((char *)xap_vm_ptr->debug_data.ascout_buf, asc_str);
}
#endif


void xap_send_error(const char *fmt,...)
{
	va_list			ap;
	char			info[1024];
	
	if (xap_vm_ptr->debug_data.error_switch == 0 || xap_vm_ptr->debug_data.send_control == 1)
		return;

	xap_send_ascout("\33[31m");
	va_start(ap, fmt);
	vsnprintf(info, 1020, fmt, ap);
	va_end(ap);

	strcat(info, "\33[37m\r\n");
	xap_send_ascout(info);
}

void xap_msg_display(u8 *info_str)
{
	int		i = 0, j = 0, linemax = 24;
	u32		msg_len;
	u32		did;
	char		show_str[2048];
	char	name[64];
	
	if (xap_vm_ptr->debug_data.send_control == 1)
		return;

	did = info_str[6] * 256 + info_str[7];

	switch(info_str[2])
	{
	case MAP_FLAG:
		strcpy(name,"MAP");
		if (xap_vm_ptr->debug_data.map_switch == 0 && xap_vm_ptr->debug_data.monitor_did != did)
		{
			if(xap_vm_ptr->debug_data.error_switch == 0 || 
				(info_str[9] != MAP_U_ABORT && info_str[9] != MAP_P_ABORT && info_str[9] != MAP_NOTICE))
				return;
		}
		if (info_str[10] == 1 || info_str[10] == 3)		// message type
		{
			sprintf(show_str, "[%04u]User ==> %s ", did,name);
			xap_send_ascout(show_str);
		}
		else
		{
			sprintf(show_str, "[%04u]User <== %s ", did,name);
			xap_send_ascout(show_str);
		}
		break;
	case IS41_FLAG:
		sprintf(name,"IS41");
		if (xap_vm_ptr->debug_data.map_switch == 0 && xap_vm_ptr->debug_data.monitor_did != did)
		{
			if(xap_vm_ptr->debug_data.error_switch == 0 || 
				(info_str[9] != MAP_U_ABORT && info_str[9] != MAP_P_ABORT && info_str[9] != MAP_NOTICE))
				return;
		}
		if (info_str[10] == 1 || info_str[10] == 3)		// message type
		{
			sprintf(show_str, "[%04u]User ==> %s ", did,name);
			xap_send_ascout(show_str);
		}
		else
		{
			sprintf(show_str, "[%04u]User <== %s ", did,name);
			xap_send_ascout(show_str);
		}
		break;
	case CAP_FLAG:
		if (xap_vm_ptr->debug_data.cap_switch == 0 && xap_vm_ptr->debug_data.monitor_did != did)
		{
			if(xap_vm_ptr->debug_data.error_switch == 0 || 
				(info_str[9] != MAP_U_ABORT && info_str[9] != MAP_P_ABORT && info_str[9] != MAP_NOTICE))
				return;
		}
		if (info_str[10] == 1 || info_str[10] == 3)		// message type
		{
			sprintf(show_str, "[%04u]User ==> CAP ", did);
			xap_send_ascout(show_str);
		}
		else
		{
			sprintf(show_str, "[%04u]User <== CAP ", did);
			xap_send_ascout(show_str);
		}
		break;
	default:
		xap_send_error("[%04u]Invalid User type:0x%02X ", did, info_str[2]);
		break;
	}
	
	switch(info_str[9])
	{
	case MAP_OPEN:
		if( info_str[10] < 3 ) // req or ind 
		{
			sprintf(show_str, "Xap_Open_%s ACN = %d , Version = %d\r\n", opr_type_desc[info_str[10]%5],info_str[11],info_str[12]);
		}
		else if( info_str[12] == 1 && info_str[13] == 1 && info_str[14] == 2)// req or ind 
		{
			sprintf(show_str, "Xap_Open_%s ACN = %d , Version = %d\r\n", opr_type_desc[info_str[10]%5],info_str[15],info_str[16]);
		}
		else 
		{
			sprintf(show_str, "Xap_Open_%s \r\n", opr_type_desc[info_str[10]%5]);
	  }
		xap_send_ascout(show_str);
		break;
	case MAP_CLOSE:
		sprintf(show_str, "Xap_Close\tmethod=%d\r\n", info_str[11]);
		xap_send_ascout(show_str);
		break;
	case MAP_U_ABORT:
		xap_send_error("Xap_UAbort\tuser reason=%s", map_uabort_desc[info_str[11] % 11]);
		break;
	case MAP_P_ABORT:
		xap_send_error("Xap_PAbort\tprovider reason=%s", map_pabort_desc[info_str[11] & 7]);
		break;
	case MAP_NOTICE:
		xap_send_error("Xap_Notice");
		break;
	case MAP_DELIMITER:
		sprintf(show_str, "Xap_Delimeter\r\n");
		xap_send_ascout(show_str);
		break;
	case MAP_LINK:
		sprintf(show_str, "Xap_Link\r\n");
		xap_send_ascout(show_str);
		break;
	default: 
		xap_get_opstr(info_str[2], info_str[9], name);
		sprintf(show_str, "%s Operation-%02X(%s)\tiid=%d\r\n",name, info_str[9], opr_type_desc[info_str[10]%5], info_str[11]);
		xap_send_ascout(show_str);
		break;
	}

	msg_len = info_str[0] * 256 + info_str[1] + 2;
	if (msg_len > 300)
	{
		xap_send_error("Invalid Length:%d", msg_len);
		msg_len = 300;
	}
			
	while(i * 24 < msg_len)
	{
		if((linemax = msg_len - 24 * i) > 24)
			linemax = 24;
		for(j = 0; j < linemax; j ++)
		{
			sprintf(show_str + 3 * j, "%02X ", info_str[24 * i + j]);
		}
		strcat(show_str, "\r\n");
		xap_send_ascout(show_str);
		i ++;
	}

	xap_send_ascout("\r\n");

}

void xap_dlg_display(struct CSLdlg_struct *dha_ptr)
{
	u8		dlg_flag;

	if (dha_ptr->dialogue_id != xap_vm_ptr->debug_data.monitor_did)
		return;
	if (dha_ptr->message_flag == REQUEST)
		dlg_flag = 2;
	else
		dlg_flag = 1;
//	tcap_disp_dlg(dha_ptr,dlg_flag);
}

void xap_cmp_display(struct CSLcmp_struct *cha_ptr)
{
	u8		dlg_flag;

	if (cha_ptr->dialogue_id != xap_vm_ptr->debug_data.monitor_did)
		return;
	if (cha_ptr->message_flag == REQUEST)
		dlg_flag = 2;
	else
		dlg_flag = 1;
//	tcap_disp_cmp(cha_ptr,dlg_flag);
}

int xap_get_response(u8 oidlen,u32 *oid,u8 *pdata,u8 *vartype)
{
	u32		ii;
	int		data_len = -1;

	ii = XAP_PREOBJ_LEN;
	switch(oid[ii])
	{
		case 1:					//measure
			break;
		case 2:					//configuration
			switch(oid[ii+2])
			{
				case 1:				//MCC
					memcpy(pdata,xap_inter_ptr->mcc,2);
					data_len = 2;
					*vartype = 0x44;
					break;
				case 2:				//MNC
					memcpy(pdata,&xap_inter_ptr->mnc,2);
					data_len = 2;
					*vartype = 0x44;
					break;
				case 3:				//CC
					memcpy(pdata,xap_inter_ptr->cc,2);
					data_len = 2;
					*vartype = 0x44;
					break;
				case 4:				//NDC
					memcpy(pdata,xap_inter_ptr->ndc,3);
					data_len = 3;
					*vartype = 0x44;
					break;
				case 5:				//International Prefix
					memcpy(pdata,xap_inter_ptr->inter_prefix,2);
					data_len = 2;
					*vartype = 0x44;
					break;
				case 6:				//National Prefix
					memcpy(pdata,xap_inter_ptr->national_prefix,2);
					data_len = 2;
					*vartype = 0x44;
					break;
				case 7:				// monitor control flag
					memcpy(pdata,xap_inter_ptr->local_prefix,2);
					data_len = 2;
					*vartype = 0x44;
					break;
				case 8:
					switch(oid[ii+2])
					{
						case 1:
							return snmpGetConvPrefix(oidlen,oid,pdata,vartype);
						break;
						case 2:
							return snmpGetGroupConvPrefix(oidlen,oid,pdata,vartype);
						break;
					}
				break;
				case 9:
					return snmpGetCliPrefix(oidlen,oid,pdata,vartype);
				break;
				case 10:
					memcpy(pdata,xap_inter_ptr->mscidToNum[oid[ii+2]],14);
					data_len = 14;
					*vartype = 4;
					break;
				break;
				case 11:
					return snmpGetPlatName(oidlen,oid,pdata,vartype);
				break;
				default:
					break;
			}
			break;
		case 3:					//status
			if (oid[ii+1] == 1)
			{
				memcpy(pdata,xap_ver,3);
				data_len = 3;
				*vartype = 4;
			}
			break;
		default:
			break;
	}
	return data_len;
}

int xap_set_response(u8 oidlen,u32 *oid,u8 *pdata,u16 datalen)
{
	u32		ii;

	ii = XAP_PREOBJ_LEN;
	switch(oid[ii])
	{
		case 1:					//measure
			break;
		case 2:					//configuration
			xap_save_system_param_flag = 1;
			switch(oid[ii+2])
			{
				case 1:				//MCC
					if (datalen != 2)
						return -1;
					memcpy(xap_inter_ptr->mcc,pdata,2);
					return 2;
				case 2:				//MNC
					if (datalen < 2)
						return -1;
					if (datalen == 2)
						memcpy(xap_inter_ptr->mnc,pdata,2);
					else
					{
						xap_inter_ptr->mnc[0] = pdata[0];
						xap_inter_ptr->mnc[1] = 0xee;
					}
					return 2;
				case 3:				//CC
					if (datalen != 2)
						return -1;
					memcpy(xap_inter_ptr->cc,pdata,2);
					return 2;
					break;
				case 4:				//NDC
					if (datalen != 3)
						return -1;
					memcpy(xap_inter_ptr->ndc,pdata,3);
					return 3;
					break;
				case 5:				//International Prefix
					if (datalen != 2)
						return -1;
					memcpy(xap_inter_ptr->inter_prefix,pdata,2);
					return 2;
					break;
				case 6:				//National Prefix
					if (datalen != 2)
						return -1;
					memcpy(xap_inter_ptr->national_prefix,pdata,2);
					return 2;
					break;
				case 7:				// debug flag control
					if (datalen != 2)
						return -1;
					memcpy(xap_inter_ptr->local_prefix,pdata,2);
					return 2;
					break;
				case 8:
					switch(oid[ii+2])
					{
						case 1:
							return snmpSetConvPrefix(oidlen,oid,pdata,datalen);
						break;
						case 2:
							return snmpSetGroupConvPrefix(oidlen,oid,pdata,datalen);
						break;
					}
				break;
				case 9:
					return snmpSetCliPrefix(oidlen,oid,pdata,datalen);
				break;
				case 10:
					if (datalen != 14)
						return -1;
					memcpy(xap_inter_ptr->mscidToNum[oid[ii+2]],pdata,14);
					return 14;
					break;
				break;
				case 11:
					return snmpSetPlatName(oidlen,oid,pdata,datalen);
				break;
				case 12:
					if(pdata[0] == 1)
					{
						xap_write_conf();
						xap_write_mscid_conf();
						saveConvPrefix();
					}
					return 1;
				break;
				default:
					break;
			}
			break;
		case 3:					//status
			if (oid[ii+1] == 2)	// system command
			{
				if (pdata[0] == 0x01)	// save system parameter
				{
					xap_write_conf();
					xap_write_mscid_conf();
					saveConvPrefix();
					return 1;
				}
				if ((pdata[0] & 0x02) > 0)//reload parameters and reset
				{
					xap_init( xap_vm_ptr->grantdid );
				}
			}
			break;
		default:
			break;
	}
	//xap_write_conf();
	return -1;
}

void xap_init_m(void)
{
	u32		str_len;
	char	temp_str[1024],info_str[1024];
	char	*cur_time;
	u8		page,ii;

	debug_set_response(XAP_ID_LEN,xap_status_id,&xap_status,1);	// set status id
	sprintf(info_str,"V%d.%d.%02d",xap_ver[0],xap_ver[1],xap_ver[2]);
	debug_set_response(XAP_ID_LEN,xap_version_id,(BYTE *)info_str,strlen(info_str));	// set module description
	debug_set_response(XAP_ID_LEN,xap_ascin_id,xap_vm_ptr->debug_data.ascin_buf,XAP_ASCIN_LEN);
	debug_set_response(XAP_ID_LEN,xap_ascout_id,xap_vm_ptr->debug_data.ascout_buf,XAP_ASCOUT_LEN);

	xap_page = 0;
	memset(xap_did,0,2);
	memset(xap_next_did,0,2);
	xap_next_did[1] = 1;
	for (page = 1;page < XAP_MAX_PAGE;page ++)
	{
		switch (page)
		{
			case 1:		// system parameter
				sprintf(info_str,"Page %d\t\tXAP system parameter\r\n\nVersion\r\nMCC\r\nMNC\r\nCC\r\nNDC\r\nInter prefix\r\nNational prefix\r\nRegister SSN\r\n",page);
				str_len = strlen(info_str);
				break;
			case 2:		// map provider status
				sprintf(temp_str,"Dialogue ID\r\nFSM state\r\nACN\r\nTimer\r\nOperation state\r\nOperation code\r\nOperation class\r\n");
				sprintf(info_str,"Page %d\t\tMAP status\r\n\n%s\nNext Dialogue ID status\r\n\n%s",page,temp_str,temp_str);
				str_len = strlen(info_str);
				break;
			case 3:		// SCF status
				sprintf(temp_str,"Dialogue ID\r\nFSM state\r\nOperation\r\nEDPs\r\nEDP_flag\r\nExpire Times\r\nTimer\r\n");
				sprintf(info_str,"Page %d\t\tSCF status\r\n\n%s\nNext Dialogue ID status\r\n\n%s",page,temp_str,temp_str);
				str_len = strlen(info_str);
				break;
			case 4:		// SSF status
				sprintf(temp_str,"Dialogue ID\r\nFSM state\r\nRelationship\r\nRequest number\r\nTssf timer\r\nO-BCSM\r\nT-BCSM\r\n");
				sprintf(info_str,"Page %d\t\tSSF status\r\n\n%s\nNext Dialogue ID status\r\n\n%s",page,temp_str,temp_str);
				str_len = strlen(info_str);
				break;
			case 5:		// xap watchdog
				sprintf(info_str,"Page %d\t\tWatch dog\r\n\n",page);
				for (ii = 0;ii < XAP_MAX_LINE;ii ++)
				{
					sprintf(temp_str,"%d--%d\r\n",ii*5,ii*5+4);
					strcat(info_str,temp_str);
				}
				str_len = strlen(info_str);
				break;
			default:
				strcpy(info_str,"NONE\r\n");
				str_len = strlen(info_str);
				break;
		}
		xap_page_title[XAP_PAGE_POINT] = page + 5;
		debug_set_response(XAP_TITLE_LEN,xap_page_title,(BYTE *)info_str,str_len);
		xap_disp_page(page);
	}
	//inquire_setmsg(XAP_PREOBJ_LEN,xap_object_id,xap_set_response);
	//inquire_getmsg(XAP_PREOBJ_LEN,xap_object_id,xap_get_response);
	xap_snmp_registration();
	xap_read_conf();
	xap_read_mscid_conf();
	readConvPrefixConf();

	xap_roaming_rules_init();	

	cur_time = GetAsciiTime();
	xap_vm_ptr->debug_data.start_time = GetAsciiTime();
	sprintf(info_str,"XAP init process completed. Init time is:%s\r",cur_time);
	xap_send_ascout(info_str);
}

u8	xap_disp_line(u8 page,u8 line)
{
	u8		temp_line;
	u8		line_len=0;
	u32		temp_did;
	struct	xapp_vm_data	*vm_ptr;

	xap_disp_ptr = xap_ver;
	switch (page)
	{
		case 1:	// system parameter
			switch (line)
			{
				case 0:		// version
					xap_disp_ptr = xap_ver;
					line_len = 3;
					break;
				case 1:		// MCC
					xap_disp_ptr = xap_inter_ptr->mcc;
					line_len = 2;
					break;
				case 2:		// MNC
					xap_disp_ptr = xap_inter_ptr->mnc;
					line_len = 2;
					break;
				case 3:		// CC
					xap_disp_ptr = xap_inter_ptr->cc;
					line_len = 2;
					break;
				case 4:		// NDC
					xap_disp_ptr = xap_inter_ptr->ndc;
					line_len = 3;
					break;
				case 5:		// international prefix
					xap_disp_ptr = xap_inter_ptr->inter_prefix;
					line_len = 2;
					break;
				case 6:		// nationla prefix
					xap_disp_ptr = xap_inter_ptr->national_prefix;
					line_len = 2;
					break;
				case 7:		// register ssn
					xap_disp_ptr = xap_inter_ptr->reg_ssn;
					line_len = MAX_XAP_SSN;
					break;
				default:
					break;
			}
			break;
		case 2:		// show the map provider state
			if (line < 10)
			{
				temp_did = xap_did[0] * 256 + xap_did[1];
				temp_line = line;
			}
			else
			{
				temp_did = (xap_next_did[0] * 256 + xap_next_did[1]) % (xap_vm_ptr->grantdid);
				temp_line = line - 10;
			}
			vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[temp_did];
			switch (temp_line)
			{
				case 0:		// dialogue id
					if (line < 10)
						xap_disp_ptr = xap_did;
					else
						xap_disp_ptr = xap_next_did;
					line_len = 2;
					break;
				case 1:		// fsm state
					xap_disp_ptr = &vm_ptr->psm_data.psm_state;
					line_len = 2;
					break;
				case 2:		// acn
					xap_disp_ptr = &vm_ptr->psm_data.acn;
					line_len = 2;
					break;
				case 3:		// timer
					xap_disp_ptr = (u8 *) &vm_ptr->psm_data.suspend_timer;
					line_len = 4;
					break;
				case 4:		// operation state
					xap_disp_ptr = vm_ptr->psm_data.opr_state;
					line_len = 20;
					break;
				case 5:		// operation code
					xap_disp_ptr = vm_ptr->psm_data.opr_code;
					line_len = 20;
					break;
				case 6:		// operation class
					xap_disp_ptr = vm_ptr->psm_data.opr_class;
					line_len = 20;
					break;
				default:
					break;
			}
			break;
		case 3:		// show the scf provider state
			break;
		case 4:		// show the ssf provider state
			break;
		case 5:
			xap_disp_ptr = (u8 *) &xap_vm_ptr->debug_data.watch_dog[line*5];
			line_len = 20;
			break;
		default:
			line_len = 0;
			break;
	}
	return line_len;
}

void xap_disp_page(u8 page)
{
	u8		line;
	u8		line_len;

	xap_page_line[XAP_PAGE_POINT] = page + 5;
	for (line = 0;line < XAP_MAX_LINE;line ++)
	{
		line_len = xap_disp_line(page,line);
		xap_page_line[XAP_LINE_POINT] = line + 2;
		debug_set_response(XAP_LINE_LEN,xap_page_line,xap_disp_ptr,line_len);
	}
}

void xap_monitor(void)
{
	u32		ii;
	char		info_str[1024],temp_str[1024];
	struct	xap_debug_struct	*debug_ptr;
	int value;

	debug_ptr = (xap_debug_struct *) &xap_vm_ptr->debug_data;
	debug_ptr->send_control = 0;
	if (strlen((char *)debug_ptr->ascin_buf) > 0)	// has command
	{
		if (strcmp((char *)debug_ptr->ascin_buf+1,"help") == 0) // show help info
		{
			sprintf(info_str,"Now the monitored module is XAP provider.\r\nVersion is R%dV%02d_%02d and start time is %s\r\n",xap_ver[0],xap_ver[1],xap_ver[2],debug_ptr->start_time);
			xap_send_ascout(info_str);
			xap_send_ascout("The XAP module command list:\r\n");
			xap_send_ascout("log all   ---- Turn on all log items\r\n");
			xap_send_ascout("log none  ---- Turn off all log items\r\n");
			xap_send_ascout("log map   ---- Turn on the map log item\r\n");
			xap_send_ascout("log cap   ---- Turn on the cap log item\r\n");
			xap_send_ascout("log error ---- Turn on the error log item\r\n");
			xap_send_ascout("log port [did] ---- Monitor the appointed dialogue id\r\n");
			xap_send_ascout("list parameter ---- Display the system parameter in XAP provider\r\n");
			xap_send_ascout("reset ---- Reset XAP provider\r\n");
		}
		else if (strcmp((char *)debug_ptr->ascin_buf+1,"clear") == 0)
			memset(debug_ptr->watch_dog,0,XAP_WTDOG_LEN*sizeof(u32));
		else if (strcmp((char *)debug_ptr->ascin_buf+1,"log none") == 0) // close all switch
		{
			debug_ptr->error_switch = 0;
			debug_ptr->map_switch = 0;
			debug_ptr->cap_switch = 0;
			xap_send_ascout("XAP all switch close\n\r");
		}
		else if (strcmp((char *)debug_ptr->ascin_buf+1,"log error") == 0)// open error switch
		{
			debug_ptr->error_switch = 1;
			xap_send_ascout("XAP error switch open\n\r");
		}
		else if (strcmp((char *)debug_ptr->ascin_buf+1,"log map") == 0)// open to map switch
		{
			debug_ptr->map_switch = 1;
			xap_send_ascout("XAP monitor map switch open\n\r");
		}
		else if (strcmp((char *)debug_ptr->ascin_buf+1,"log cap") == 0)// open to map switch
		{
			debug_ptr->cap_switch = 1;
			xap_send_ascout("XAP monitor cap switch open\n\r");
		}
		else if (strcmp((char *)debug_ptr->ascin_buf+1,"log all") == 0)// open all switch
		{
			debug_ptr->error_switch = 1;
			debug_ptr->map_switch = 1;
			debug_ptr->cap_switch = 1;
			xap_send_ascout("XAP all switch open\n\r");
		}
		else if (strncmp((char *)debug_ptr->ascin_buf+1,"did ",4) == 0)	// change section page
		{
			ii = atol((char *)debug_ptr->ascin_buf+5) % (xap_vm_ptr->grantdid);
			xap_did[0] = ii >> 8;
			xap_did[1] = ii & 0xff;
			xap_next_did[0] = (ii+1) >> 8;
			xap_next_did[1] = (ii+1) & 0xff;
		}
		else if (strncmp((char *)debug_ptr->ascin_buf+1,"log port ",9) == 0)	// monitor the did
		{
			ii = atol((char *)debug_ptr->ascin_buf+10);
			if (ii >= (xap_vm_ptr->grantdid))
				xap_send_ascout("The appointed dialogue id is not expected\r\n");
			else
				debug_ptr->monitor_did = ii;
		}
		else if (strcmp((char *)debug_ptr->ascin_buf+1,"list parameter") == 0)	// diaplay system parameter
		{
			xap_get_addstr(temp_str,xap_inter_ptr->mcc,2);
			sprintf(info_str,"The XAP provider system parameter is:\r\nMCC(Mobile Country Code): %s\r\n",temp_str);
			xap_send_ascout(info_str);
			xap_get_addstr(temp_str,xap_inter_ptr->mnc,2);
			sprintf(info_str,"MNC(Mobile Network Code): %s\r\n",temp_str);
			xap_send_ascout(info_str);
			xap_get_addstr(temp_str,xap_inter_ptr->cc,2);
			sprintf(info_str,"CC(Country Code): %s\r\n",temp_str);
			xap_send_ascout(info_str);
			xap_get_addstr(temp_str,xap_inter_ptr->ndc,3);
			sprintf(info_str,"NDC(National Destination Code): %s\r\n",temp_str);
			xap_send_ascout(info_str);
			xap_get_addstr(temp_str,xap_inter_ptr->inter_prefix,2);
			sprintf(info_str,"International prefix: %s\r\n",temp_str);
			xap_send_ascout(info_str);
			xap_get_addstr(temp_str,xap_inter_ptr->national_prefix,2);
			sprintf(info_str,"National prefix: %s\r\n",temp_str);
			xap_send_ascout(info_str);
		}
		else if (strcmp((char *)debug_ptr->ascin_buf+1,"reset") == 0)	// diaplay system parameter
		{
			//xap_init( xap_vm_ptr->grantdid );
		}
		else if (strcmp((char *)debug_ptr->ascin_buf+1,"reload acn") == 0)	// diaplay system parameter
		{
			init_mappconst();
			init_cappconst();
		}
		else if (strncasecmp((char *)debug_ptr->ascin_buf+1,"set timer=", 10) == 0)	// set establishment timer
		{
		       int ivalue;
		       
		       ivalue = atoi((char *)debug_ptr->ascin_buf+1+10);
		       if(ivalue>=180 && ivalue<=36000)
		       {
				xap_inter_ptr->establishment_timer = ivalue;
				xap_write_conf();
				sprintf(info_str,"set XAP establishment timer=%d, save it!\r\n", ivalue);
				xap_send_ascout(info_str);
		       }
		       else
		       {
			       sprintf(info_str,"Invalid timer value, the XAP establishment timer should be 180-36000\r\n");
				xap_send_ascout(info_str);
		       }
		}
		else if (strcmp((char *)debug_ptr->ascin_buf+1,"est timer?") == 0)	// diaplay system parameter
		{
			sprintf(info_str,"XAP establishment timer=%d\r\n",xap_inter_ptr->establishment_timer);
			xap_send_ascout(info_str);
		}
		else if (strncasecmp((char *)debug_ptr->ascin_buf+1,"test rrule ", 11) == 0)
		{
			value = xap_roaming_rule_test((char *)debug_ptr->ascin_buf+12);
			if(value < 0)
				sprintf(info_str,"rule NOT found for the vlr %s \r\n",debug_ptr->ascin_buf+12);
			else
				sprintf(info_str,"rule found for the vlr %s index=%d\r\n",debug_ptr->ascin_buf+12, value);
			xap_send_ascout(info_str);
		}

		debug_ptr->ascin_buf[0] = '\0';
	}
/*	for (ii = 1;ii < XAP_MAX_PAGE;ii ++)
		xap_disp_page(ii);*/
	xap_check_save_param();
}

void xap_watch_dog(u32 wd_site)
{
	if (wd_site > XAP_WTDOG_LEN)
		return;
	xap_vm_ptr->debug_data.watch_dog[wd_site] ++;
}

void xap_logdebug(const char *fmt,...)
{
	va_list			ap;
	char			info[1024];
	
	va_start(ap, fmt);
	vsnprintf(info, 1020, fmt, ap);
	va_end(ap);

	return xap_send_ascout(info);
}

void xap_set_conv_param_flag()
{
	xap_save_conv_param_flag = 1;
}

void xap_set_roaming_rule_flag()
{
	xap_save_roaming_rule_flag = 1;
}

void xap_check_save_param()
{
	static int xap_check_param_counter = 0;

	if(xap_check_param_counter++%100==0)//10 senconds
	{
		if(xap_save_conv_param_flag )
		{
			saveConvPrefix();
			xap_save_conv_param_flag = 0;	
		}
		if(xap_save_system_param_flag)
		{
			xap_save_system_param_flag  = 0;
			xap_write_conf();
		}
		if(xap_save_roaming_rule_flag)
		{
			xap_save_roaming_rule_flag = 0;
			xap_save_roaming_rule();
		}
		
	}
}

int xap_get_est_timer()
{
    if(xap_inter_ptr->establishment_timer>=DLGPEND_TIME)
        return xap_inter_ptr->establishment_timer;
    else
    	return DLGPEND_TIME;
}

