
#include    "../include/includes.h"
#include    "../include/message.h"
#include    "../include/ppsm.h"
#include    "../include/cdrme.h"
#include    "../include/ramdata.h"
#include    "../include/mfunc.h"
#include    "../include/config.h"
#include    "../include/param.h"
#include    "../include/precard.h"


#include    "../include/plat_inc.h"
#include    "../../../../plat/scf/src/include/scfpub.h"
#include    "../../../../plat/scf/src/include/scfmsg.h"
#include	"../../../opr/src/include/OprApi.h"

#include	"../../../opr/src/include/function.h"

extern _state_machine	*smshm_ptr;
extern u_short	debug_messages;
extern int	logMsgFlag;
extern struct	timeval tvnow;
extern _ram_data	*ramshm_ptr;

extern	OPR_PARAM	opr_param;	
extern	PPSParamStruct	ppsParam;


extern int StuffCapMessage();
extern int ppsDebugCapMsg();
extern int GetMaxCallDuration();
extern int GetAccountVoiceID();
extern int GetAccountLastCallInfo(_account_info *ptr, _last_call_info *pInfo);
extern int UpdateAccountLastCDR();
extern int FindPPSTableIndex();
extern int UpdateAccountExpiration();
extern int ListAllPortStatus();
extern int SendScfTcEND(u_short portid);
extern int WaitingForRechargeCardPasswordResponse(u_short portid);
extern int RechargeRequestProc(u_short portid);
extern int AddPPSSubsData();
extern int DeletePPSSubsData();
extern int FindPPSSubsStoreIndex();

extern	int	ReportUserStatusByImsiBcd(BYTE *msisdn);
extern  int IsDeleteOprTrailAccount();
extern	int  PPSDeleteOprAccountUser(BYTE *msisdnbcd,u_long PpsProc);/*pps -> opr */

extern int CallingCardWaitingForSpecialResourceReport(_state_data *shmp);

extern long AucGetRandSeed (  );
int WaitingForSrfResponse(u_short portid,u8 operation);

#define 	ONE_DAY		(60*60*24)
#define		TWO_DAY		2*ONE_DAY

extern char			masterFlag;

enum opr_state
{
	opr_mng_keep_state,
	opr_mng_exit
};

enum sub_state
{
	S_REC_OPR_CHECK_ACCOUNT_STATUS = 1,
	S_REC_OPR_INPUT_PWD,
	S_REC_OPR_CHECK_PWD,
	S_REC_OPR_INPUT_IMEI,
	S_WAIT_FOR_IMEI,
	S_REC_OPR_INPUT_IMEI_AGAIN,
	S_REGISTER_IMEI,
	S_WAIT_PLAYREGISTER_COMPLTE,	
	S_CREATE_PPS,
	S_REGISTER_DONE,
	S_REC_OPR_REGISTER_COMPLETE,

	S_REC_OPR_SWITH_PROMT,
	S_REC_OPR_SWITCH_KEY,
	S_OPR_SWITCH_OPR_DOING,
	S_OPR_SWITCH_ROAMING_DOING,
	S_REC_OPR_REPLAY_OR_BACK,
	S_REC_SWITCH_FAIL,
	S_REC_OPR_SWITCH_FINISH,

	S_REC_OPR_ENQUIRE_KEY,
	S_REC_OPR_ENQUIRE,
	S_REC_OPR_ENQUIRE_COMPLETE,
	
	S_OPRREISTER,
	S_OPRENQIRE,
	S_OPRSWITCH
};

enum srf_response
{
	WAITFORIMEI = 0,
	WAITFORMAINKEY ,
	WAITFORSWITCHKEY ,
	WAITFORENQUIREKEY ,
	WAITFORENDORBACKKEY
};

int IsOprNumber(char *number)
{
	int retval=0;
	int	len;
	u_char *oprNumber;

	oprNumber = ppsParam.ppsTables.serviceNumber[OPRNumberPosition].number;		
	if(oprNumber[0] == 0) return 0;
	len = strlen(oprNumber);
	if(!strncasecmp(number,oprNumber,len))
		retval = 1;
	
	return retval;
}

int handleReplayBackKey(u_short portid)
{
	int retval1 = opr_mng_keep_state,retval;	
	_state_data 	*shmp;
	
	PutLogFunID("handleReplayBackKey");

	shmp = (_state_data *)&smshm_ptr->state_data;
	shmp += portid;
	
	retval = WaitingForSrfResponse(portid,WAITFORENDORBACKKEY);			
	switch(retval)
	{
		case 0:
		break;
		case 1:
			switch(shmp->process_info.tmpDigits[0])
			{
				case 11:/*	to main menu	*/
					shmp->process_info.sub_state = 0;
				break;	
				case 0:
				default:
					shmp->process_info.funnel = 0;
					shmp->process_info.serviceInput = 0;
					shmp->process_info.maxPCUInfoLen = 1;	/*	max length of input digit	*/
					shmp->process_info.voiceID = INPUT_REPLAY_OR_BACK;
					SendPromptAndCollectUserInfo(portid);
					shmp->process_info.sub_state_2 = S_REC_OPR_REPLAY_OR_BACK;
				break;
			}						
		break;
		default:
			retval1 = opr_mng_exit;
		break;				
	}
	return retval1;
}


void SendMsisdnPrompt(u_short portid)
{
   	int						dlgid,invokeid=0,len;
   	u_char					u_msisdn[12];
   	char					buf[32];
   	CAP_Message				cap_message;
   	CapArg					capArg;
   	CapMessageID			*pMID;
	CapPlayAnnouncement		*pPlayAnnouncement;
	_state_data    			*shmp=(_state_data *) &smshm_ptr->state_data;

	PutLogFunID("SendMsisdnPrompt");

	shmp += portid;   
  	AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir);
   
	dlgid  = shmp->context_info.dialogue_id;
   
	capArg.ocode = CAP_OC_PlayAnnouncement;
	capArg.message_flag = REQUEST;
	capArg.port_id = portid;
	capArg.dialogue_id = dlgid;
	capArg.invoke_id = invokeid;
   	capArg.version = shmp->context_info.acn_ver;

	pPlayAnnouncement = &capArg.msg_list.playAnnouncementArg;
	pPlayAnnouncement->optional_flag = 0x03;
	pPlayAnnouncement->disconnectFromIPForbidden = 0x01;
	pPlayAnnouncement->requestAnnouncementComplete = 0x01;

	pPlayAnnouncement->informationToSend.choice_id = 0x00;
	pPlayAnnouncement->informationToSend.inbandInfo.messageID.choice_id = 0x03;
	/* review need 2003-10-08,user prefered language type not taken account  */
						
	pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID;
	pMID->variableMessage.elementaryMessageID =
		GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 +
			+shmp->process_info.voiceID;
	
	pMID->variableMessage.variableParts.num = 1;

	pMID->variableMessage.variableParts.variablePart[0].choice_id = 1;
	strcpy(buf,shmp->process_info.tmpDigits);
	len = strlen(buf);
	if(len>18) len = 18;
	ppsAsciiToBcdR(u_msisdn,buf,((len+1)/2)*2);
	pMID->variableMessage.variableParts.variablePart[0].number[0] = (len+1)/2+1;
	if(len%2==0)
		pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x04;
	else
		pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x24;
	memcpy(&pMID->variableMessage.variableParts.variablePart[0].number[2],
			u_msisdn,
			(len+1)/2);
	
	pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07;
	pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 1;
	pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00;
	pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01; /* 1seconds */
	
	StuffCapMessage(capArg,&cap_message);
	WriteScfMsg(cap_message);

#if DEBUG
	if(debug_messages<=MAX_DEBUG_MESSAGES)	
	if((logMsgFlag & 0x02)|| shmp->process_info.logMsisdn)
	{
		ppsDebugCapMsg(&cap_message,1);
		debug_messages ++;
	}
#endif
}


int SendMsisdnPromptToSrf(u_short portid)
{
	int						len;
	_state_data 			*shmp;	
	
	PutLogFunID("SendMsisdnPromptToSrf");

	shmp = (_state_data *)&smshm_ptr->state_data;
	shmp += portid;
	
	len = strlen(shmp->caller_info.number);
		
	shmp->process_info.voiceID = YOUR_NUMBER_IS; 		
	memcpy(shmp->process_info.tmpDigits,shmp->caller_info.number,len);
	shmp->process_info.tmpDigits[len]=0;

	SendMsisdnPrompt(portid);	   	
	return	1;
}

int WaitingForSrfResponse(u_short portid,u8 operation)
{
	int				retval = 0,dlgid,msglen,key,len;
	CAP_Message		capmsg;
	CapArg			capArg;
    CapPromptAndCollectUserInformation	*pPCUI;
	
	_state_data *shmp;

	PutLogFunID("WaitingForFavoriteNumberAddConfirmResponse");

	shmp = (_state_data *)&smshm_ptr->state_data;
	shmp += portid;

	dlgid = shmp->context_info.dialogue_id;

	if(!ReadScfMsg(&capmsg,dlgid))
	{
		return retval;
	}

#if DEBUG
	if(debug_messages<=MAX_DEBUG_MESSAGES)
    if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn)
	{  
	    debug_messages ++;
		ppsDebugCapMsg(&capmsg,0);
	}
#endif

	switch(capmsg.msgOperaCode)
	{
		case CAP_OC_PromptAndCollectUserInformation:
			AddPPSStatistics(MIBPPS_PCUI_RES,shmp->process_info.dir);
			shmp->process_info.funnel = 0;
			msglen = capmsg.msgContent[3]*256 + capmsg.msgContent[4];
			capArg.version = shmp->context_info.acn_ver;
			if(decode_capmsg(&capmsg.msgContent[5],
							msglen,
							capmsg.msgOperaCode,
							CAP_CONFIRM,
							&capArg)<0)
			{
					return (retval=4);
			}
			pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg;
			len = pPCUI->digitsResponse[0];
			switch(operation)
			{
				case WAITFORIMEI:
					if((len - 1) != IMEI_LEN) 
					{
						if(shmp->process_info.serviceInput++>SERVICE_INPUT_NUM)
						{
						 	return (retval = 3);
						}
						return (retval = 2);
					}								
					if(pPCUI->digitsResponse[1] & 0x20)
					{
						pPCUI->digitsResponse[len] |=0xF0;
					}			
										
					ppsBcdToAsciiR(shmp->process_info.tmpDigits,
									&pPCUI->digitsResponse[2],
									2*(len-1));
					retval = 1;
				break;
				case WAITFORMAINKEY:
				case WAITFORSWITCHKEY:
				case WAITFORENQUIREKEY:
				case WAITFORENDORBACKKEY:
					key = pPCUI->digitsResponse[2];					
					switch(operation)
					{
						case WAITFORMAINKEY:
							//if(((key >= 0 && key <= 3))||(key == 11))
							{
								shmp->process_info.tmpDigits[0] = key;
								retval = 1;
							}
						break;
						case WAITFORSWITCHKEY:
						case WAITFORENQUIREKEY:
							//if((key >= 0 && key <= 2)||(key == 11))
							{
								shmp->process_info.tmpDigits[0] = key;
								retval = 1;
							}
						break;																							
						case WAITFORENDORBACKKEY:
							//if(key == 0 || key == 11)
							{
								shmp->process_info.tmpDigits[0] = key;
								retval = 1;
							}	
						break;		
					}					
				}										
		break;
		case CAP_O_UABORT:
		case CAP_O_PABORT:
		default:
			retval = 4;
		break;
	}
	return retval;
}

static int SMLCIReister(FixSMLCICommand *cmdLine,FixSMLCIResult *resultLine)
{
	_state_data 	*shmp;
	int	causeCode,result;
	long 	expired_date;
	u_short portid;
    
    	PutLogFunID("FixSMLCIReister");       		
	
	if(logMsgFlag == DEBUG_ALL)							
		DebugMsg(debugmib.display.asciiOut,
				"\33[33m PPS SMLCI Reister OPR service\33[0m");
		
	portid = AssignProcID(0);
	if(portid < 0 || portid >= MAX_FSM_PROCESS)
	{
		causeCode = ReturnOprCantAssignProc;
		resultLine->result = OPRFAIL; 
		DetermineCause(causeCode,resultLine->cause);
		if(logMsgFlag & DEBUG_ERROR)							
		DebugMsg(debugmib.display.asciiOut,
				"\33[31m SMLCI Reister Fail:PPS can't assign proc\33[0m");
		return -1;
	}
	
	shmp = (_state_data *)&smshm_ptr->state_data;
	shmp += portid;
	
	causeCode = RechargeCardRequest(portid,cmdLine->prepaidPwd, &result);
	if(causeCode != 1)/*	cardPwd has problem	*/
	{
		resultLine->result = OPRFAIL; 
		DetermineCause(causeCode,resultLine->cause);		
		if(logMsgFlag & DEBUG_ERROR)							
		DebugMsg(debugmib.display.asciiOut,
				"\33[31m SMLCI Reister Fail:Recharge Card problem:%s\33[0m",resultLine->cause);
		ReleasePortStatus(portid); 
		return -1;
	}	
	memcpy(shmp->process_info.tmpDigits,cmdLine->imei,IMEI_IMSI_ASCII_LEN);
	causeCode = FixSMCLIRegisterOPR(shmp,resultLine->pin);
	if(causeCode < 0)
	{
		resultLine->result = OPRFAIL; 
		DetermineCause(causeCode,resultLine->cause);	
		if(logMsgFlag & DEBUG_ERROR)							
		DebugMsg(debugmib.display.asciiOut,
				"\33[31m SMLCI Reister Fail:Opr register problem:%s\33[0m",resultLine->cause);	
		ReleasePortStatus(portid); 
		return -1;
	}	
	memcpy(resultLine->msisdn,shmp->caller_info.number,MAX_MSISDN_ALEN+1);
	RechargeRequestProc(portid);
	sprintf(resultLine->balance,"%32ld",(long)GetBalance(&shmp->caller_info));
    expired_date = GetExpiration(&shmp->caller_info);
    AsciiTime(resultLine->expire_date,expired_date);    
   	if(logMsgFlag == DEBUG_ALL)					
		DebugMsg(debugmib.display.asciiOut,
				"\33[33m SMLCI Reister success,msisdn:%s,pin:%s,balance:%ld,expireDate:%s\33[0m"
				,resultLine->msisdn,resultLine->pin,resultLine->balance,resultLine->expire_date);	
	ReleasePortStatus(portid);   
    return 1;
}
int  OMCReisterCommand(BYTE oidlen, DWORD *oid, BYTE *pdata, WORD datalen)
{
	int	i,vallen,totalLen;
	int	loop=0;
	BYTE	pdata1[1600],pdata2[1600],pflag;
	u_short	ptagcode;
	char	tagbuf[32];
	ASN_BUF	*asnbuf, asnbuf1;
	ASN_BUF	*asnbuf2, asnbuf3;	
	
	FixSMLCICommand cmdLine;
	FixSMLCIResult resultLine;
	u8			   resultSize;
	
	PutLogFunID("OMCReisterCommand");
	
	memset(pdata1,0,datalen+1);
	memcpy(pdata1,pdata,datalen);
	pdata1[datalen]=0;

	asnbuf = &asnbuf1;

	AsnEncode(pdata,1600,asnbuf);
	asnbuf2 = &asnbuf3;

	AsnDecode(pdata1, datalen, UNIT_STORE_ACCOUNT, NULL, asnbuf2);
	
	resultSize = sizeof(FixSMLCIResult);
	memset(&cmdLine,0,sizeof(FixSMLCICommand));
	memset(&resultLine,0,resultSize);
	for(loop=1;loop<3;loop++)
	{     
		sprintf(tagbuf,"-%d",loop);
		if((vallen=GetAnyTLV(tagbuf,1024,pdata2,&pflag,&ptagcode,asnbuf2))<0){
			break;
		}
		sprintf(tagbuf,"%d",ptagcode);
		pdata2[vallen]=0;

		switch(ptagcode)
		{			
			case 0x01://imei
				if(vallen == 0) 
				{
					resultLine.result = OPRFAIL; 
					memcpy(resultLine.cause,"IMEI length error",32);
					if(logMsgFlag == DEBUG_ERROR)	
					DebugMsg(debugmib.display.asciiOut,
					"\33[31m IMEI length error,can't be NULL\33[0m");
					break;
				}
				if(vallen != IMEI_IMSI_ASCII_LEN)
				{
					resultLine.result = OPRFAIL; 
					memcpy(resultLine.cause,"IMEI length error",32);
					if(logMsgFlag == DEBUG_ERROR)	
					DebugMsg(debugmib.display.asciiOut,
					"\33[31m IMEI length error,must be %d\33[0m",IMEI_IMSI_ASCII_LEN);
					break;
				}
				for(i=0;i<vallen;i++)
				{
					if(pdata2[i]>'9' || pdata2[i]<'0') 
					{
						resultLine.result = OPRFAIL; 
						memcpy(resultLine.cause,"Error IMEI,not digit",32);
						if(logMsgFlag == DEBUG_ERROR)	
						DebugMsg(debugmib.display.asciiOut,
						"\33[31m %s:%s \33[0m",resultLine.cause,pdata2);						
						break;
					}
				}			    
				if(i >= vallen)
				{
					memcpy(cmdLine.imei,pdata2,vallen);
					cmdLine.imei[vallen] = 0; 				
				}
			break;
			case 0x02://prepaid card password
				for(i=0;i<vallen;i++)
				{
					if(pdata2[i]>'9' || pdata2[i]<'0') 
					{
						resultLine.result = OPRFAIL; 
						memcpy(resultLine.cause,"Error prepaid card password,not digit",32);
						if(logMsgFlag == DEBUG_ERROR)	
						DebugMsg(debugmib.display.asciiOut,
						"\33[31m %s:%s\33[0m",resultLine.cause,pdata2);						
						break;
					}
				}		
				if(i >= vallen)
				{
					memcpy(cmdLine.prepaidPwd,pdata2,vallen);
					cmdLine.prepaidPwd[vallen] = 0; 
				}
			break;
		}//switch
	}//for	
	SMLCIReister(&cmdLine,&resultLine);
	for(i=1;i<=8;i++)
	{
		sprintf(tagbuf,"-%d",i);
		if((vallen=GetAnyTLV(tagbuf,1024,pdata2,&pflag,&ptagcode,asnbuf2))<0){
			break;
		}
		sprintf(tagbuf,"%d",ptagcode);
		switch(ptagcode)
		{			
			case 1:/* imei	*/
				totalLen = add_tlv(tagbuf,IMEI_IMSI_ASCII_LEN,cmdLine.imei,0x80,asnbuf);
			break;
			case 2:/*	prepaid card password	*/
				totalLen = add_tlv(tagbuf,strlen(cmdLine.prepaidPwd),cmdLine.prepaidPwd,0x80,asnbuf);
			break;
			case 3:/*	result	*/
				{
					u_char tmp[16];				
					memset(tmp,0,16);
					if(resultLine.result == OPRFAIL)
						memcpy(tmp,"Fail",4);
					else
						memcpy(tmp,"Success",7);
					totalLen = add_tlv(tagbuf,strlen(tmp),tmp,0x80,asnbuf);
				}
			break;
			case 4:/*	msisdn	*/
				if(resultLine.result == OPRFAIL)
				{
					totalLen = add_null(tagbuf,0x80,asnbuf);	
				}
				else
				{
					totalLen = add_tlv(tagbuf,strlen(resultLine.msisdn),resultLine.msisdn,0x80,asnbuf);
				}
			break;
			case 5:/*	pin		*/
				if(resultLine.result == OPRFAIL)
				{
					totalLen = add_null(tagbuf,0x80,asnbuf);	
				}
				else
				{
					totalLen = add_tlv(tagbuf,strlen(resultLine.pin),resultLine.pin,0x80,asnbuf);
				}
			break;
			case 6:/*	balance	*/
				if(resultLine.result == OPRFAIL)
				{
					totalLen = add_null(tagbuf,0x80,asnbuf);	
				}
				else
				{
					totalLen = add_tlv(tagbuf,strlen(resultLine.balance),resultLine.balance,0x80,asnbuf);
				}
			break;
			case 7:/*	expire date */
				if(resultLine.result == OPRFAIL)
				{
					totalLen = add_null(tagbuf,0x80,asnbuf);	
				}
				else
				{
					totalLen = add_tlv(tagbuf,strlen(resultLine.expire_date),resultLine.expire_date,0x80,asnbuf);
				}
			break;
			case 8:/*	fail cause	*/
				if(resultLine.result == OPRSUCCESS)
				{
					totalLen = add_null(tagbuf,0x80,asnbuf);	
				}
				else
				{
					totalLen = add_tlv(tagbuf,strlen(resultLine.cause),resultLine.cause,0x80,asnbuf);
				}
			break;	
		}	
	}
	return totalLen;
}

int ppsRegisterOprUser(u_short portid)
{
	int							retval,retval1 = opr_mng_keep_state,result;
	_state_data 				*shmp;
	u8							imsi[24],*tmpimsi;
	PPS_REGISTER_OPR_WITH_IMEI 	mapContent;
	OPR_CREATE_PPS_USER 		mapContentCreatePps;
	int							caller_status;
	
	PutLogFunID("RegisterProc");

	shmp = (_state_data *)&smshm_ptr->state_data;
	shmp += portid;
	retval = rec_mng_keep_state;

	switch(shmp->process_info.sub_state_2)
	{						
		case S_REC_OPR_CHECK_ACCOUNT_STATUS:			
			if( xappCheckIfLocalMSISDN(shmp->caller_info.number) == 1)/* local msisdn */
			{							
				shmp->process_info.voiceID = SERIVCE_NOT_APPLIED;
				shmp->process_info.funnel = 0;
				shmp->process_info.srfRelease = 0;
				SendSrfPlayAnnouncement(portid);
				shmp->process_info.sub_state_2 = S_REC_OPR_REGISTER_COMPLETE;
				break;
			}			
			shmp->process_info.serviceInput = 0;
			shmp->process_info.sub_state_2 = S_REC_OPR_INPUT_PWD;			
		break;				
		case S_REC_OPR_INPUT_PWD:		
			shmp->process_info.funnel = 0;			
			shmp->process_info.voiceID = INPUT_PRECARD_PWD;
			shmp->process_info.endOfReplyDigit[0] = 1;
			shmp->process_info.endOfReplyDigit[1] = 12;
			shmp->process_info.maxPCUInfoLen = 20;
			SendPromptAndCollectUserInfo(portid);
			shmp->process_info.sub_state_2 = S_REC_OPR_CHECK_PWD;
		break;
		case S_REC_OPR_CHECK_PWD:
			retval = WaitingForRechargeCardPasswordResponse(portid);
			switch(retval)
			{
				case 0:
				break; 
				case 1:												
					shmp->process_info.sub_state_2 = S_REC_OPR_INPUT_IMEI;
					shmp->process_info.count = 0;					
				break;
				case 2:
					shmp->process_info.srfRelease = 0;
					shmp->process_info.voiceID = REGISTER_OPR_FAIL_PWD_ERROR;
					shmp->process_info.maxPCUInfoLen = 20;
					shmp->process_info.endOfReplyDigit[0] = 1;
					shmp->process_info.endOfReplyDigit[1] = 12;
					SendPromptAndCollectUserInfo(portid);
					shmp->process_info.funnel = 0;
					shmp->process_info.sub_state_2 = S_REC_OPR_CHECK_PWD;															
				break;
				case 3:
					retval1 = opr_mng_exit;
				break;
			}
		break;
		case S_REC_OPR_INPUT_IMEI:
			shmp->process_info.funnel = 0;
			shmp->process_info.serviceInput = 0;
			shmp->process_info.voiceID = INPUT_MOBILE_IMEI;
			shmp->process_info.endOfReplyDigit[0] = 1;
			shmp->process_info.endOfReplyDigit[1] = 12;
			shmp->process_info.maxPCUInfoLen = MAX_ASCII_NUMBER_LEN;
			SendPromptAndCollectUserInfo(portid);
			shmp->process_info.sub_state_2 = S_WAIT_FOR_IMEI;
			shmp->process_info.count = 0;					
		break;
		case S_WAIT_FOR_IMEI:
			retval = WaitingForSrfResponse(portid,WAITFORIMEI);
			switch(retval)
			{
				case 0:
				break;
				case 1:/*	successful inputed imei	*/
					shmp->process_info.funnel = 0;
					shmp->process_info.serviceInput = 0;
					shmp->process_info.maxPCUInfoLen = IMEI_IMSI_ASCII_LEN;
					if(shmp->process_info.count == 0)
					{
						shmp->process_info.count++;								
						shmp->process_info.voiceID = INPUT_MOBILE_IMEI_AGAIN;												
						shmp->process_info.sub_state_2 = S_REC_OPR_INPUT_IMEI_AGAIN;
						SendPromptAndCollectUserInfo(portid);												
						break;
					}
					else
					{
						shmp->process_info.count = 0;
						if(memcmp(shmp->process_info.routing_number,shmp->process_info.tmpDigits,IMEI_IMSI_ASCII_LEN) == 0)
						{
							shmp->process_info.sub_state_2 = S_REGISTER_IMEI;
							break;
						}
						else
						{
							shmp->process_info.voiceID = IMEI_REGISTER_FAIL_IMEI_NOT_SAME;
							shmp->process_info.sub_state_2 = S_REC_OPR_REGISTER_COMPLETE;	
							shmp->process_info.funnel = 0;
							shmp->process_info.srfRelease = 0;
							SendSrfPlayAnnouncement(portid);
							break;
						}
					}					
				break;
				case 2:
					shmp->process_info.count = 0;
					shmp->process_info.srfRelease = 0;					
					shmp->process_info.voiceID = REGISTER_OPR_IMEI_ERROR;
					shmp->process_info.maxPCUInfoLen = MAX_ASCII_NUMBER_LEN;
					SendPromptAndCollectUserInfo(portid);
					shmp->process_info.funnel = 0;
					shmp->process_info.sub_state_2 = S_WAIT_FOR_IMEI;
				break;
				case 3:
					retval1 = opr_mng_exit;
				break;
			}
		break;
		case S_REC_OPR_INPUT_IMEI_AGAIN:
			memset(shmp->process_info.routing_number,0,18);
			memcpy(shmp->process_info.routing_number,shmp->process_info.tmpDigits,strlen(shmp->process_info.tmpDigits));						
			memset(shmp->process_info.tmpDigits,0,MAX_ASCII_NUMBER_LEN);
			shmp->process_info.sub_state_2 = S_WAIT_FOR_IMEI;
		break;
		case S_REGISTER_IMEI:/*		invoke opr		*/					
			if(shmp->caller_info.IMSI[0] == 0)/* Fix register OPR service	*/
			{				
				_account_info         tmpInfo;
	
				memcpy(&tmpInfo,&shmp->caller_info,sizeof(_account_info));
								
				shmp->process_info.rechargeByOther = 1;
				tmpimsi	= NULL;
				
				shmp->process_info.tmpDigits[strlen(shmp->process_info.tmpDigits)] = 0;
				shmp->process_info.sub_state_2 = S_REGISTER_DONE;
				shmp->process_info.oc = C_FIX_REGISTER_DONE;
				shmp->process_info.u_error = OPRSUCCESS;
				
				result = FixSMCLIRegisterOPR(shmp,mapContentCreatePps.pin);		
				if(result<0)								
				{
					shmp->process_info.u_error = OPRFAIL;
				}
				else
				{					
					memcpy(&shmp->recharge_info,&shmp->caller_info,sizeof(_account_info));
				}
				memcpy(&shmp->caller_info,&tmpInfo,sizeof(_account_info));								
			}
			else 							/*	MS register OPR service for itself	*/
			{
				shmp->process_info.rechargeByOther = 0;
				ppsBcdToAsciiR(imsi,shmp->caller_info.IMSI,IMEI_IMSI_ASCII_LEN+1);
				StringCut(imsi,'F');
				if(strlen(imsi) != IMEI_IMSI_ASCII_LEN)
					DebugMsg(debugmib.display.asciiOut,
					"\n\33[31m[portid:%d]Pps REGISTER IMEI fail,imsi length error,! = 15\33[0m(%ld.%ld)",
					portid,tvnow.tv_sec,tvnow.tv_usec);
				
				memcpy(mapContent.imei,shmp->process_info.tmpDigits,strlen(shmp->process_info.tmpDigits));
				memcpy(mapContent.imsi,imsi,IMEI_IMSI_ASCII_LEN);
				result = mapMsgSendToOpr(PPS_REGISTER_OPR_WITH_IMEI_REQ,portid,-1,
										(BYTE *)&mapContent,sizeof(PPS_REGISTER_OPR_WITH_IMEI));
				if(result > 0)
				{
					shmp->process_info.voiceID = IMEI_REGISTERING;
					shmp->process_info.funnel = 0;
					shmp->process_info.srfRelease = 0;
					SendSrfPlayAnnouncement(portid);
					shmp->process_info.sub_state_2 = S_WAIT_PLAYREGISTER_COMPLTE;				
				}
				else
				{
					shmp->process_info.voiceID = IMEI_REGISTER_FAIL;
					shmp->process_info.funnel = 0;
					shmp->process_info.srfRelease = 0;
					SendSrfPlayAnnouncement(portid);
					shmp->process_info.sub_state_2 = S_REC_OPR_REGISTER_COMPLETE;
				}
			}			
		break;
		case S_WAIT_PLAYREGISTER_COMPLTE:
			result = CallingCardWaitingForSpecialResourceReport(shmp);
			if(result == pin_mng_keep_state)
				break;					
			else if(result == 1)	
			{																		
				shmp->process_info.sub_state_2 = S_CREATE_PPS;	
			}
			else
				retval1 = opr_mng_exit;	
		break;		
		case S_CREATE_PPS:
			if(shmp->process_info.oc != C_CREATE_PPS 
				&& shmp->process_info.oc != C_MS_REGISTER_DONE)
				break;			
				
			if(shmp->process_info.oc == C_CREATE_PPS)
			{
				shmp->process_info.oc = 0;
				result = CreatePPsUserForOpr(shmp,mapContentCreatePps.pin);				
				mapContentCreatePps.result = result?OPRSUCCESS:OPRFAIL;
				result = mapMsgSendToOpr(OPR_CREATE_PPS_USER_RES,portid,shmp->process_info.correlationID,
						(BYTE *)&mapContentCreatePps,sizeof(OPR_CREATE_PPS_USER));	
				shmp->process_info.sub_state_2 = S_REGISTER_DONE;				
				if(mapContentCreatePps.result == OPRFAIL)
				{
					shmp->process_info.oc = C_MS_REGISTER_DONE;
					shmp->process_info.u_error = OPRFAIL;
				}
				else/*	only success	*/
					break;
			}
			else
			{
				shmp->process_info.sub_state_2 = S_REGISTER_DONE;					
			}								
		case S_REGISTER_DONE:	
			if(shmp->process_info.oc != C_MS_REGISTER_DONE && 
				shmp->process_info.oc != C_FIX_REGISTER_DONE)
				break;
			shmp->process_info.oc = 0;
			result =shmp->process_info.u_error;	
			if(result == OPRSUCCESS)
			{				
				if(shmp->process_info.oc == C_MS_REGISTER_DONE)
					shmp->process_info.voiceID = MS_REGISTER_SUCCESS;	
				else
					shmp->process_info.voiceID = FIX_REGISTER_SUCCESS;	
				RechargeRequestProc(portid);	
			}
			else
			{
				shmp->process_info.voiceID = IMEI_REGISTER_FAIL;
			}			
			shmp->process_info.funnel = 0;
			shmp->process_info.srfRelease = 0;
			SendSrfPlayAnnouncement(portid);
			shmp->process_info.sub_state_2 = S_REC_OPR_REGISTER_COMPLETE;			
		break;
		case S_REC_OPR_REGISTER_COMPLETE:
			result = CallingCardWaitingForSpecialResourceReport(shmp);
			if(result == pin_mng_keep_state)
				break;					
			else if(result == 1)	
			{																		
				shmp->process_info.funnel = 0;
				shmp->process_info.serviceInput = 0;
				shmp->process_info.maxPCUInfoLen = 1;	/*	max length of input digit	*/
				shmp->process_info.voiceID = INPUT_REPLAY_OR_BACK;
				SendPromptAndCollectUserInfo(portid);
				shmp->process_info.sub_state_2 = S_REC_OPR_REPLAY_OR_BACK;	
			}
			else
				retval1 = opr_mng_exit;		
		case S_REC_OPR_REPLAY_OR_BACK:			
			retval1 = handleReplayBackKey(portid);
		break;
		default:
		break;
	}
	return retval1;
}



int ppsCreateOprUser(u_short portid)
{
	
	return 1;
}

int ppsInqueryOprUser(u_short portid)
{
	u8	retval,retval1= opr_mng_keep_state;
	_state_data 	*shmp;
	int status,result;
	
	PutLogFunID("ppsInqueryOprUser");

	shmp = (_state_data *)&smshm_ptr->state_data;
	shmp += portid;
	
	switch(shmp->process_info.sub_state_2)
	{
		case S_REC_OPR_ENQUIRE:/*	send inquery promt 	*/
			shmp->process_info.funnel = 0;
			shmp->process_info.serviceInput = 0;
			shmp->process_info.voiceID = INPUT_INQUERY_KEY;
			shmp->process_info.maxPCUInfoLen = 1;
			SendPromptAndCollectUserInfo(portid);
			shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE_KEY;		
		break;		
		case S_REC_OPR_ENQUIRE_KEY:
			retval = WaitingForSrfResponse(portid,WAITFORENQUIREKEY);			
			switch(retval)
			{
				case 0:
				break;
				case 1:
					status = ReportUserStatusByImsiBcd(shmp->caller_info.IMSI);
					/*
					OprWithOutRoamAgreement_OPRState,
 	OprWithRoamAgreeement_OPRState,
 	OprWithRoamAgreeement_RoamingState,
 	*/
					if(status != OprWithOutRoamAgreement_OPRState 
						&& status != OprWithRoamAgreeement_OPRState
						&& status != OprWithRoamAgreeement_RoamingState)
					{							
						shmp->process_info.voiceID = NOT_REGISTER_STATUS;
						shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE_COMPLETE;
						SendSrfPlayAnnouncement(portid);
						break;
					}
					
					switch(shmp->process_info.tmpDigits[0])
					{
						case 1:/*	inquery msisdn*/							
							SendMsisdnPromptToSrf(portid);
							shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE_COMPLETE;	
						break;
						case 2:/*	inquery status:opr state or roaming state	*/
							shmp->process_info.funnel = 0;
							shmp->process_info.serviceInput = 0;
							shmp->process_info.maxPCUInfoLen = 1;							
							if(status == OprWithOutRoamAgreement_OPRState
								|| status == OprWithRoamAgreeement_OPRState)
								shmp->process_info.voiceID = OPR_STATUS;
							else if(status == OprWithRoamAgreeement_RoamingState)
								shmp->process_info.voiceID = ROAMING_STATUS;
							else
								shmp->process_info.voiceID = NOT_REGISTER_STATUS;
							SendSrfPlayAnnouncement(portid);
							shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE_COMPLETE;	
						break;						
						case 11:/*	'*' back to */
							shmp->process_info.sub_state = 0;
						break;
						case 0:/*	replay	*/
							shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE;
						break;
						default:
							shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE;
						break;		
					}		
				break;
				case 2:
					shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE;
				break;
				case 3:
				default:
					retval1 = opr_mng_exit;
				break;
			}						
		break;		
		case S_REC_OPR_ENQUIRE_COMPLETE:
			result = CallingCardWaitingForSpecialResourceReport(shmp);
			if(result == pin_mng_keep_state)
				break;					
			else if(result == 1)	
			{																		
				shmp->process_info.funnel = 0;
				shmp->process_info.serviceInput = 0;
				shmp->process_info.maxPCUInfoLen = 1;	/*	max length of input digit	*/
				shmp->process_info.voiceID = INPUT_REPLAY_OR_BACK;
				SendPromptAndCollectUserInfo(portid);
				shmp->process_info.sub_state_2 = S_REC_OPR_REPLAY_OR_BACK;	
			}
			else
				retval1 = opr_mng_exit;		
		break;		
		case S_REC_OPR_REPLAY_OR_BACK:
			retval1 = handleReplayBackKey(portid);
		break;
		default:
			retval1 = opr_mng_exit;
		break;
	}	
	return retval1;
}

int ppsSwtichOprUser(u_short portid)
{
	int				retval,retval1 = opr_mng_keep_state,result;
	_state_data 	*shmp;
	PPS_SWITCH_OPR 	mapContent;
	int				status;
		
	PutLogFunID("ppsSwtichOprUser");

	shmp = (_state_data *)&smshm_ptr->state_data;
	shmp += portid;
	
	switch(shmp->process_info.sub_state_2)
	{
		case S_REC_OPR_SWITH_PROMT:/*	send switch promt 	*/
			shmp->process_info.funnel = 0;
			shmp->process_info.serviceInput = 0;
			shmp->process_info.maxPCUInfoLen = 1;

			status = ReportUserStatusByImsiBcd(shmp->caller_info.IMSI);
			if(status != OprWithOutRoamAgreement_OPRState 
				&& status != OprWithRoamAgreeement_OPRState
				&& status != OprWithRoamAgreeement_RoamingState)/* not registered */
			{							
				shmp->process_info.voiceID = NOT_REGISTER_STATUS;
				shmp->process_info.sub_state_2 = S_REC_SWITCH_FAIL;
				break;
			}	
					
			shmp->process_info.voiceID = INPUT_SWITCH_KEY;
			SendPromptAndCollectUserInfo(portid);
			shmp->process_info.sub_state_2 = S_REC_OPR_SWITCH_KEY;		
		break;
		case S_REC_OPR_SWITCH_KEY:
			retval = WaitingForSrfResponse(portid,WAITFORSWITCHKEY);			
			switch(retval)
			{
				case 0:
				break;
				case 1:
					shmp->process_info.funnel = 0;
					shmp->process_info.serviceInput = 0;
					shmp->process_info.maxPCUInfoLen = 1;	/*	max length of input digit	*/												
					switch(shmp->process_info.tmpDigits[0])
					{
						case 1:/*	swith to opr state	*/
							memcpy(mapContent.imsi,shmp->caller_info.IMSI,8);
							mapContent.key = 1;
							result = mapMsgSendToOpr(PPS_SWITCH_OPR_REQ,portid,-1,
									(BYTE *)&mapContent,sizeof(PPS_SWITCH_OPR));
							if(retval > 0)
								shmp->process_info.sub_state_2 = S_OPR_SWITCH_OPR_DOING;							
							else
							{
								shmp->process_info.sub_state_2 = S_REC_SWITCH_FAIL;
								shmp->process_info.voiceID = INPUT_SWITCH_TO_OPR_FAIL;	
							}
						break;
						case 2:/*	switch to roaming state	*/
							memcpy(mapContent.imsi,shmp->caller_info.IMSI,8);
							mapContent.key = 2;
							result = mapMsgSendToOpr(PPS_SWITCH_OPR_REQ,portid,-1,
									(BYTE *)&mapContent,sizeof(PPS_SWITCH_OPR));
							if(retval > 0)
								shmp->process_info.sub_state_2 = S_OPR_SWITCH_ROAMING_DOING;
							else
							{
								shmp->process_info.sub_state_2 = S_REC_SWITCH_FAIL;
								shmp->process_info.voiceID = INPUT_SWITCH_TO_ROAMING_FAIL;
							}
						break;
						case 11:/*	back to */
							shmp->process_info.sub_state = 0;						
						break;
						case 0:/*	replay	*/
							shmp->process_info.sub_state_2 = S_REC_OPR_SWITH_PROMT;		
						break;
						default:
							shmp->process_info.sub_state_2 = S_REC_OPR_SWITH_PROMT;
						break;		
					}					
				break;
				case 2:
					shmp->process_info.sub_state_2 = S_REC_OPR_SWITH_PROMT;
				break;
				case 3:
				default:
					retval1 = opr_mng_exit;
				break;
			}
		break;
		case S_OPR_SWITCH_OPR_DOING:						
			if(shmp->process_info.oc != C_SWITCH_DONE)
				break;
			result = shmp->process_info.u_error;
			if(result == OPRSUCCESS) /*	switch success,but vlr not do location update	*/
			{
				shmp->process_info.voiceID = INPUT_SWITCH_TO_OPR_SUCCESS;								
			}
			else /*	switch fail	*/
			{
				shmp->process_info.voiceID = INPUT_SWITCH_TO_OPR_FAIL;	
			}														
			SendSrfPlayAnnouncement(portid);
			shmp->process_info.sub_state_2 = S_REC_OPR_SWITCH_FINISH;
		break;
		case S_OPR_SWITCH_ROAMING_DOING:
			if(shmp->process_info.oc != C_SWITCH_DONE)
				break;
			result = shmp->process_info.u_error;
			if(result == OPRSUCCESS) /*	switch success,but vlr not do location update	*/
			{
				shmp->process_info.voiceID = INPUT_SWITCH_TO_ROAMING_SUCCESS;								
			}
			else /*	switch fail	*/
			{
				shmp->process_info.voiceID = INPUT_SWITCH_TO_ROAMING_FAIL;	
			}														
			SendSrfPlayAnnouncement(portid);
			shmp->process_info.sub_state_2 = S_REC_OPR_SWITCH_FINISH;
		break;	
		case S_REC_SWITCH_FAIL:
			shmp->process_info.funnel = 0;
			shmp->process_info.serviceInput = 0;
			shmp->process_info.maxPCUInfoLen = 1;	/*	max length of input digit	*/
			SendSrfPlayAnnouncement(portid);
			shmp->process_info.sub_state_2 = S_REC_OPR_SWITCH_FINISH;
		break;
		case S_REC_OPR_SWITCH_FINISH:
			shmp->process_info.oc = 0;
			shmp->process_info.u_error = 0;
			result = CallingCardWaitingForSpecialResourceReport(shmp);
			if(result == pin_mng_keep_state)
				break;					
			else if(result == 1)	
			{																		
				shmp->process_info.funnel = 0;
				shmp->process_info.serviceInput = 0;
				shmp->process_info.maxPCUInfoLen = 1;	/*	max length of input digit	*/
				shmp->process_info.voiceID = INPUT_REPLAY_OR_BACK;
				SendPromptAndCollectUserInfo(portid);
				shmp->process_info.sub_state_2 = S_REC_OPR_REPLAY_OR_BACK;	
			}
			else
				retval1 = opr_mng_exit;				
		break;
		case S_REC_OPR_REPLAY_OR_BACK:
			retval1 = handleReplayBackKey(portid);
		break;
		default:
			retval1 = opr_mng_exit;
		break;
	}
	return retval1;
}


int OprManagementProc(u_short portid)
{
	u8 retval,retval1 = opr_mng_keep_state;
	_state_data 	*shmp;

	PutLogFunID("OprManagementProc");

	shmp = (_state_data *)&smshm_ptr->state_data;
	shmp += portid;
	
	if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER)
		return (retval = opr_mng_exit);
	if(shmp->process_info.disconnectForwardConnection == 1)
	{
		SendScfTcEND(portid);
		return (retval = opr_mng_exit);
	}
	
	switch(shmp->process_info.sub_state)	
	{
		case 0:
			shmp->process_info.funnel = 0;
			shmp->process_info.serviceInput = 0;
			shmp->process_info.voiceID = OPR_SERVICE_SELECT_PROMPT;
			shmp->process_info.maxPCUInfoLen = 1;
			shmp->process_info.sub_state = 1;
			SendPromptAndCollectUserInfo(portid);
		break;
		case 1:
			retval = WaitingForSrfResponse(portid,WAITFORMAINKEY);			
			switch(retval)
			{
				case 0:
				break;
				case 1:
					switch(shmp->process_info.tmpDigits[0])
					{
						case 1:	/*	register	*/
							shmp->process_info.sub_state = S_OPRREISTER;
							shmp->process_info.sub_state_2 = S_REC_OPR_CHECK_ACCOUNT_STATUS;
						break;
						case 2:	/* inquery	*/
							shmp->process_info.sub_state = S_OPRENQIRE;
							shmp->process_info.sub_state_2 = S_REC_OPR_ENQUIRE;
						break;
						case 3:	/*	switch	*/
							shmp->process_info.sub_state = S_OPRSWITCH;
							shmp->process_info.sub_state_2 = S_REC_OPR_SWITH_PROMT;
						break;			
						case 0:	/*	replay	*/
							shmp->process_info.sub_state = 0;
						break;
						case 11:	/* '*' exit */				
							retval1 = opr_mng_exit;
						break;			
						default:	
							shmp->process_info.sub_state = 0;						
						break;	
					}
				break;
				case 2:
					shmp->process_info.sub_state = 0;
				break;
				case 3:
				default:
					retval1 = opr_mng_exit;
				break;
			}
		break;
		case S_OPRREISTER:
			retval1 = ppsRegisterOprUser(portid);
		break;
		case S_OPRENQIRE:			
			retval1 = ppsInqueryOprUser(portid);
		break;
		case S_OPRSWITCH:			
			retval1 = ppsSwtichOprUser(portid);				
		break;
		default:
			retval1 = opr_mng_exit;
		break;			
	}		
	return retval1;
}


void getRandomPin(char *pin)
{
	long long 	rand_num;
	char 		tmp[32]={0};
	char		opr_state[256]={0};
	
	initstate ( AucGetRandSeed (  ), opr_state, 256 );
	setstate ( opr_state );
	srandom ( AucGetRandSeed (  ) );          
    rand_num = random (  );
    sprintf(tmp,"%lld",rand_num);
    memcpy(pin,tmp,6);    
}

BYTE CreatePPsUserForOpr(_state_data *shmpq,u_char *pin)/*opr-> pps */
{
	int				store_index,len;
	_prepaid_info	shmp;
	BYTE 			*msisdn;
	
	msisdn = shmpq->caller_info.number;
	len = msisdn[MAX_MSISDN_ALEN];
	if(len>MAX_MSISDN_ALEN || len<OPPS_MIN_MSISDN_ALEN) 
	{
		return 0;	
	}
	msisdn[len] = 0;
	store_index = FindPPSSubsStoreIndex(atoll(msisdn));
	if(store_index>=0 && store_index<MAX_SUBS_RECORD)
	{		
		if(logMsgFlag & DEBUG_ERROR)
			DebugMsg(debugmib.display.asciiOut,
			"\33[35mPPS create OPR user fail,MSISDN:%s exist!\n\33[0m",msisdn);
		debugmib.watch_dog[63]++;			
		return 0;
	}
	
	memset(&shmp,0,sizeof(_prepaid_info));	
	AsciiToBcd(shmp.msisdn,msisdn,MAX_MSISDN_ALEN);
	if(len %2 == 0)
		shmp.msisdn[len/2] = 0xFF;
	else
		shmp.msisdn[len/2] |= 0x0F;	

	shmp.msisdn[MAX_MSISDN_BLEN-1] = len;		
	shmp.status = T_OPRTRIAL;
	shmp.first_used_date = tvnow.tv_sec;
	shmp.promo_date = tvnow.tv_sec;
	getRandomPin(shmp.pin);
	memcpy(pin,shmp.pin,MAX_PIN_LEN);
	shmp.mo_expiration_date = tvnow.tv_sec + ppsParam.serviceControl.callingCardVadilityDays*24*3600; /* outgoing */
	shmp.mt_expiration_date = tvnow.tv_sec + ppsParam.serviceControl.callingCardVadilityDays*24*3600; /* incoming */
	shmp.cos_id = opr_param.oprCosId;
	store_index = AddPPSSubsData(&shmp);
	if(store_index >= 0)
	{				
		GetAccountPos(&shmpq->caller_info);
		if(logMsgFlag == DEBUG_ALL)
			DebugMsg(debugmib.display.asciiOut,
				"Opr receive create pps subscriber %s success! (%ld.%ld)",
					msisdn,tvnow.tv_sec,tvnow.tv_usec);		
	}
	else
	{
		if(logMsgFlag & DEBUG_ERROR)
			DebugMsg(debugmib.display.asciiOut,
					"Opr receive create pps subscriber %s fail! (%ld.%ld)",
						msisdn,tvnow.tv_sec,tvnow.tv_usec);
		return 0;
	}
	SendAccountRealSync(store_index,0.0,0.0,3);
	return 1;
}

void PpsDelete_OPRTRAIL_Account()
{
	static u_long	PpsDelete_OPRTRAIL_Account_instance = 0;;
	_prepaid_info 	*shmp;
	u_long			i,j,loop,Account_instance;
	
	if( !masterFlag )
		return;
	
	if(!IsDeleteOprTrailAccount())
		return;
	for(loop = 0;loop < 10;loop++)
	{		
		if(PpsDelete_OPRTRAIL_Account_instance >=MSISDN_HEAD_NUM*UNIT_STORE_ACCOUNT )
			PpsDelete_OPRTRAIL_Account_instance = 0;
		i=PpsDelete_OPRTRAIL_Account_instance/UNIT_STORE_ACCOUNT;
		j=PpsDelete_OPRTRAIL_Account_instance%UNIT_STORE_ACCOUNT;		
		shmp = &ramshm_ptr->prepaid_data.prepaid_info[i][j];
		Account_instance = PpsDelete_OPRTRAIL_Account_instance++;
		if(shmp->status != T_OPRTRIAL)
			continue;		
		if(PPSDeleteOprAccountUser(shmp->msisdn,0))
		{
			SendAccountRealSync(Account_instance,0.0,0.0,4);
			break;
		}		
	}		
}

void PpsDeleteExpiredOprAccount(_prepaid_info *shmp,u_long instance,u8 expiredFlag)
{				
	if(!masterFlag || !expiredFlag || shmp->cos_id != opr_param.oprCosId)
		return ;					
		/*	be going to delete Expired Opr user	*/															
	if(PPSDeleteOprAccountUser(shmp->msisdn,0))
	{
		SendAccountRealSync(instance,0.0,0.0,4);
	}		
}

void PpsHanldeOprProc()
{
	ppsGetOprMessage();	
}

