
#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/callingCard.h"

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

extern u_short			debug_messages;
extern int		  		logMsgFlag;
extern int 				ppsDebugCapMsg();
extern _ram_data    	*ramshm_ptr;
extern	_state_machine	*smshm_ptr;
extern int SendAccountInfoBySMPP();

extern	PPSParamStruct	ppsParam;


extern int	CheckPINValidity(_account_info *ptr, char *pin);
extern void SendAccountBalanceBySrf(u_short portid);
extern int WaitingForRechargeCardPasswordResponse(u_short portid);
extern int RechargeRequestProc(u_short portid);

int CallingCardSendReleaseCall(u_short portid);

/* need change _crd_param struct*/
int IsCallingCardNumber(u_char *dstNumber)
{		
	int retval=0;
	int	len;
	u_char *callingNumber;
	
	callingNumber = ppsParam.ppsTables.serviceNumber[VirtualCallingCardNumberPosition].number;
	
	if(callingNumber[0] == 0) return 0;
	len = strlen((char *)callingNumber);
	if(!strncasecmp((char *)dstNumber, (char *)callingNumber, len))
		retval = 1;
	
	return retval;
}
	
int WaitForMainMenu(_state_data *shmp,u_short portid)
{
	int key = -1,dlgid,msglen,len;	
	CAP_Message		capmsg;
	CapArg			capArg;
    CapPromptAndCollectUserInformation	*pPCUI;
	
	PutLogFunID("WaitForMainMenu");	
	
	if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER)
	{		
		shmp->process_info.tcos = CALLER_EXPIRIED; 
		CallingCardSendReleaseCall(portid);
		return pin_mng_exit;
	}
	
	dlgid = shmp->context_info.dialogue_id;
	if(!ReadScfMsg(&capmsg,dlgid))
	{
		return key;
	}

#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((char *)&capmsg.msgContent[5],
							msglen,
							capmsg.msgOperaCode,
							CAP_CONFIRM,
							&capArg)<0)
			{
				return key;
			}
			pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg;
			len = pPCUI->digitsResponse[0];
			if(len<2 || len>12)
				return -1;

			key = pPCUI->digitsResponse[2];
			/*
			key = pPCUI->digitsResponse[2]&0x0F;
				
			if((key < ExitCallingCard) ||(key > TransferAccount))			
			{
				return -1;
			}
			*/
		break;
		case CAP_O_UABORT:
		case CAP_O_PABORT:
		default:
		break;
	}
	return key;
}

int WaitingForPin(_state_data *shmp,u8 type)
{
	/*
		type 	0:caller
				1:called
	*/
	int				retval=pin_mng_keep_state,dlgid,msglen,len;	
	CAP_Message		capmsg;
	CapArg			capArg;
    CapPromptAndCollectUserInformation	*pPCUI;
    _account_info	*call_type;
    
    PutLogFunID("WaitingForInputCallingCardAccountResponse");
    dlgid = shmp->context_info.dialogue_id;
	if(!ReadScfMsg(&capmsg,dlgid))
		return retval;			
	#if DEBUG
	if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn)
	{  
		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((char *)&capmsg.msgContent[5],
							msglen,
							capmsg.msgOperaCode,
							CAP_CONFIRM,
							&capArg)<0)
			{
				return (retval = pin_mng_exit);  //timeout ,exit 			
			}
			pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg;
			len = pPCUI->digitsResponse[0];
			if(len<2 || len>12)
				return (retval = pin_mng_exit);  //timeout ,exit 			
			len --;
			if(pPCUI->digitsResponse[1] & 0x20)
			{
				pPCUI->digitsResponse[len+1] |= 0xF0;
				len =len * 2-1;
			}
			else
				len *=2;
			if( len != MAX_PIN_LEN) //max language types = 5
			{
				if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
				{
					return (retval = pin_mng_exit);
				}					
				return retval = 2;
			}
			ppsBcdToAsciiR(shmp->process_info.tmpDigits,
							&pPCUI->digitsResponse[2],
							len);
			shmp->process_info.tmpDigits[MAX_PIN_LEN] = 0;
			if(type == 0)
				call_type = &shmp->caller_info;
			else 
				call_type = &shmp->called_info;
			 			
			if(!CheckPINValidity(call_type,shmp->process_info.tmpDigits))
			{
				if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
				{
					return (retval = pin_mng_exit);
				}									
				return retval = 2;
			}
			retval = 1;
		break;
	}    	
    return 	retval;
}

int WaitingForInputCallingCardAccountResponse(_state_data *shmp)
{
	int				retval=pin_mng_keep_state,dlgid,msglen,len;	
	CAP_Message		capmsg;
	CapArg			capArg;
    CapPromptAndCollectUserInformation	*pPCUI;
	
	PutLogFunID("WaitingForInputCallingCardAccountResponse");

	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((char *)&capmsg.msgContent[5],
							msglen,
							capmsg.msgOperaCode,
							CAP_CONFIRM,
							&capArg)<0)
			{
				return (retval = 3);
			}
			pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg;
			len = pPCUI->digitsResponse[0];
			if(len>11) len = 11;
			if(len<=2) //
			{
				if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
				{
					return (retval = 3);
				}
				return (retval = 2);
			}

			if(pPCUI->digitsResponse[1] & 0x20)
			{
				pPCUI->digitsResponse[len] |=0xF0;
			}
			memset(shmp->cdr_info.msisdn,0xFF,10);
			memcpy(shmp->cdr_info.msisdn,
				   &pPCUI->digitsResponse[2],
					len-1);			
			ppsBcdToAsciiR((char *)shmp->caller_info.number,&pPCUI->digitsResponse[2],2*(len-1));
			StringCut((char *)shmp->caller_info.number,'F');
			if(GetAccountPos(&shmp->caller_info) == FALSE)
			{
				if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
				{
					return (retval = 3);
				}
				return (retval = 2);
			}
			shmp->caller_info.status = GetAccountStatus(&shmp->caller_info);
			GetAccountCosID(&shmp->caller_info);				
			retval = 1;
		break;
		case CAP_O_UABORT:
		case CAP_O_PABORT:
		default:
			retval = 3;
		break;
	}
	return retval;
}

int WaitingForInputCallingCardAccountResponse_ccc(_state_data *shmp)
{
	int				retval=pin_mng_keep_state,dlgid,msglen,len;	
	CAP_Message		capmsg;
	CapArg			capArg;
      CapPromptAndCollectUserInformation	*pPCUI;
	char			      card_hrn[32];
	
	PutLogFunID("WaitingForInputCallingCardAccountResponse_ccc");

	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((char *)&capmsg.msgContent[5],
							msglen,
							capmsg.msgOperaCode,
							CAP_CONFIRM,
							&capArg)<0)
			{
				return (retval = 3);
			}
			pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg;
			len = pPCUI->digitsResponse[0];
			if(len>11) len = 11;
			if(len<=2) //
			{
				if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
				{
					return (retval = 3);
				}
				return (retval = 2);
			}

			if(pPCUI->digitsResponse[1] & 0x20)
			{
				pPCUI->digitsResponse[len] |=0xF0;
			}


		   len --;

		    if(pPCUI->digitsResponse[1] & 0x80)
		    pPCUI->digitsResponse[len] |= 0xF0;
			
		    memset(shmp->cdr_info.caller, 0xFF, 10);
		    memcpy(shmp->cdr_info.caller, &pPCUI->digitsResponse[2], len);
		    ppsBcdToAsciiR(card_hrn, &pPCUI->digitsResponse[2], len*2);

		    strcpy((char *)shmp->caller_info.number, card_hrn);                

		   if(1)
		   {
		   	int result;
			if(RechargeCardRequest(shmp->process_info.portid, card_hrn, &result) != 1)
			  	retval = 2;
			else
			{
				UpdateRechargeCard(shmp->process_info.portid, CARD_AS_CC_USED);
				retval = 1;
			}
		   }
		break;
		case CAP_O_UABORT:
		case CAP_O_PABORT:
		default:
			retval = 3;
		break;
	}
	return retval;
}

int WaitingForInputCalledNumber(_state_data *shmp)
{	
	int				retval=pin_mng_keep_state,dlgid,msglen,len;	
	CAP_Message		capmsg;
	CapArg			capArg;
    CapPromptAndCollectUserInformation	*pPCUI;
	_state_data 	*callOutShmp;

	PutLogFunID("WaitingForInputCalledNumber");

	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((char *)&capmsg.msgContent[5],
							msglen,
							capmsg.msgOperaCode,
							CAP_CONFIRM,
							&capArg)<0)
			{
				return (retval = 3);
			}
			pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg;
			len = pPCUI->digitsResponse[0];
			if(len>11) len = 11;
			if(len<=2) //
			{
				if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
				{
					return (retval = 3);
				}
				return (retval = 2);
			}

			if(pPCUI->digitsResponse[1] & 0x20)
			{
				pPCUI->digitsResponse[len] |=0xF0;
			}
							
			dlgid = shmp->process_info.correlationID;
			callOutShmp = (_state_data *)&smshm_ptr->state_data;
			callOutShmp += dlgid;			
			callOutShmp->context_info.callType = CT_MO_CALL;
			memset(callOutShmp->cdr_info.msisdn,0xFF,10);
			memcpy(callOutShmp->cdr_info.msisdn,
				   &pPCUI->digitsResponse[2],
					len-1);			
			ppsBcdToAsciiR((char *)callOutShmp->charge_info.number,&pPCUI->digitsResponse[2],2*(len-1));
			StringCut((char *)callOutShmp->charge_info.number,'F');																
			retval = 1;
		break;
		case CAP_O_UABORT:
		case CAP_O_PABORT:
		default:
			retval = 3;
		break;
	}
	return retval;
}


int WaitingForInputTransferOutAccount_LIMITED(_state_data *shmp)
{
	int				retval=pin_mng_keep_state,dlgid,msglen,len;
	CAP_Message		capmsg;
	CapArg			capArg;
    CapPromptAndCollectUserInformation	*pPCUI;
	
	PutLogFunID("WaitingForInputTransferOutAccount");

	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((char *)&capmsg.msgContent[5],
							msglen,
							capmsg.msgOperaCode,
							CAP_CONFIRM,
							&capArg)<0)
			{
				return (retval = 3);
			}
			pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg;
			len = pPCUI->digitsResponse[0];
			if(len>11) len = 11;
			if(len<=2) //
			{
				if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
				{
					return (retval = 3);
				}
				return (retval = 2);
			}

			if(pPCUI->digitsResponse[1] & 0x20)
			{
				pPCUI->digitsResponse[len] |=0xF0;
			}
			memset(shmp->cdr_info.msisdn,0xFF,10);
			memcpy(shmp->cdr_info.msisdn,
				   &pPCUI->digitsResponse[2],
					len-1);			
			ppsBcdToAsciiR((char *)shmp->called_info.number,&pPCUI->digitsResponse[2],2*(len-1));
			StringCut((char *)shmp->called_info.number,'F');
			if(GetAccountPos(&shmp->called_info) == FALSE)
			{
				if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
				{
					return (retval = 3);
				}
				return (retval = 2);
			}
			shmp->called_info.status = GetAccountStatus(&shmp->called_info);
			GetAccountCosID(&shmp->called_info);				
			retval = 1;
		break;
		case CAP_O_UABORT:
		case CAP_O_PABORT:
		default:
			retval = 3;
		break;
	}
	return retval;	
}

int	CallingCardWaitingForSpecialResourceReport(_state_data *shmp)
{
	int				retval=pin_mng_keep_state,dlgid;
	CAP_Message		capmsg;

	PutLogFunID("WaitingForSpecialResourceReport");	

	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_SpecializedResourceReport:
		    AddPPSStatistics(MIBPPS_SPE_RUS_RPT,shmp->process_info.dir);
		    retval = 1;
		break;
		default:
			retval = 2;
	}
	return retval;
}

int CallingCardInquiryManageProc(u_short portid)
{
	int				retval,dlgid;
	int				caller_status,instance;
	CAP_Message		capmsg;
	COSTable			*cosTableItem;
	_state_data *shmp;

	PutLogFunID("CallingCardInquiryManageProc");

	shmp = (_state_data *)&smshm_ptr->state_data;
	shmp += portid;
	retval = pin_mng_keep_state;
	
	switch(shmp->process_info.sub_state)
	{
		case S_INQ_SEND_PROMPT:
		caller_status = GetAccountStatus(&shmp->caller_info);
		if(caller_status == T_NORMAL) 
		{
			cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id];
			if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenInquiry)
			{
				SendAccountInfoBySMPP(
						&shmp->caller_info,
						shmp->called_info.number);  
			}
							
			SendAccountInfoPromptToSrf(portid,FALSE,TRUE);
			shmp->process_info.funnel = 0;
			shmp->process_info.srfRelease = 0x01;
			shmp->process_info.sub_state = S_INQ_SRR;
		}
		else 
		{
			if((caller_status == T_FRESH || caller_status == T_OPRTRIAL)
				&& shmp->caller_info.head<MSISDN_HEAD_NUM)
			{
				cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id];
				if(cosTableItem->accountValidity[0].activiationByInquiryIs)
				{
					UpdateAccountStatus(shmp->caller_info.head,
										shmp->caller_info.tail,
										T_NORMAL);
					UpdateAccountFirstUsedDate(
										shmp->caller_info.head,
										shmp->caller_info.tail);
					UpdateExpirationFirstInquiry(
										&shmp->caller_info,
										cosTableItem->accountValidity[0].validiDaysActivatedByInquiringAccountWithZeroBalance
										);
					instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT 
										+ shmp->caller_info.tail;
					SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT);
					if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenInquiry)
					{
						SendAccountInfoBySMPP(
								&shmp->caller_info,
								shmp->called_info.number);  
					}
							
					SendAccountInfoPromptToSrf(portid,FALSE,TRUE);
					shmp->process_info.funnel = 0;
					shmp->process_info.srfRelease = 0x01;
					shmp->process_info.sub_state = S_INQ_SRR;
					return retval;
				}
			}
			else
			{
				shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS;
				shmp->process_info.srfRelease = 0;
				SendSrfPlayAnnouncement(portid);
				shmp->process_info.sub_state = S_INQ_SRR0;
			}
		}
		break;
		case S_INQ_SRR0:
		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
		retval = pin_mng_exit_to_main_menu;
		break;
		case S_INQ_SRR:				
		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

		if(capmsg.msgOperaCode !=CAP_OC_SpecializedResourceReport)
		{
			if(debug_messages<=MAX_DEBUG_MESSAGES)
			if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn)
			{  
				debug_messages ++;
				DebugMsg(debugmib.display.asciiOut,"< Error message received >");
			}
			return (retval=pin_mng_exit_to_main_menu);
		}
		AddPPSStatistics(MIBPPS_SPE_RUS_RPT,shmp->process_info.dir);
		retval = pin_mng_exit_to_main_menu;
		break;
		default:
			retval = pin_mng_exit_to_main_menu;
		break;
	}
	
	return retval;
}

int CallingCardSendReleaseCall(u_short portid)
{
	_state_data 	*shmp,*shnmp;
			
	PutLogFunID("CallingCardSendReleaseCall");
	shmp = (_state_data *)&smshm_ptr->state_data;
	shnmp = (_state_data *)&smshm_ptr->state_data;
	shmp += portid;
	shnmp += shmp->process_info.correlationID;	
	shnmp->process_info.tcos = shmp->process_info.tcos;
	shnmp->process_info.disconnectForwardConnection = 1;	    	
	return pin_mng_exit;
}


int CallingCardRechargeManageProc(u_short portid)
{
	int				retval,retval1,dlgid;
	int				caller_status;
	CAP_Message		capmsg;	
	_state_data *shmp;

	PutLogFunID("CallingCardRechargeManageProc");

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

	if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER)
	{
		CallingCardSendReleaseCall(portid);
		return (retval = pin_mng_exit_to_main_menu);
	}    

	switch(shmp->process_info.sub_state)
	{
		case S_REC_CHECK_ACCOUNT_STATUS:
			caller_status = GetAccountStatus(&shmp->caller_info);
			if( caller_status != T_NORMAL &&
				caller_status != T_FRESH &&
				caller_status != T_SUSPEND &&
				caller_status != T_OPRTRIAL	)
			{
				shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS;
				shmp->process_info.srfRelease = 1;
				SendSrfPlayAnnouncement(portid);
				shmp->process_info.tcos = NORMAL_CLEARING;
				shmp->process_info.sub_state  = S_REC_WAIT_SRR;
				return retval;
			}
			shmp->process_info.sub_state = S_REC_PLAY_BALANCE;		
		break;				
		break;				
		case S_REC_PLAY_BALANCE:
			shmp->process_info.funnel = 0;
			SendAccountInfoPromptToSrf(portid,TRUE,FALSE);
			shmp->process_info.sub_state = S_REC_WAIT_SRR0;
		break;
		case S_REC_WAIT_SRR0:
			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
	
			if(capmsg.msgOperaCode !=CAP_OC_SpecializedResourceReport)
			{
				if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn)
				{  
					DebugMsg(debugmib.display.asciiOut,"< Error message received >");
				}
			}
			AddPPSStatistics(MIBPPS_SPE_RUS_RPT,shmp->process_info.dir);		
			shmp->process_info.sub_state = S_REC_INPUT_PWD;			
		break;				
		case S_REC_INPUT_PWD:
			shmp->process_info.funnel = 0;
			shmp->process_info.serviceInput = 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 = S_REC_CHECK_PWD;
		break;
		case S_REC_CHECK_PWD:
			retval1 = WaitingForRechargeCardPasswordResponse(portid);
			switch(retval1)
			{
				case 0:
				break;
				case 1:
				RechargeRequestProc(portid);
				shmp->process_info.srfRelease = 0;
				shmp->process_info.maxPCUInfoLen = 1;
				SendRechargeInfoPromptToSrf(portid);
				shmp->process_info.funnel = 0;
				shmp->process_info.sub_state = S_REC_WAIT_SRR;
				break;
				case 2:
				shmp->process_info.srfRelease = 0;
				shmp->process_info.voiceID = RECHARGE_FAILED;
				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 = S_REC_CHECK_PWD;
				break;
				case 3:
				retval = pin_mng_exit_to_main_menu;
				break;
			}
		break;
		case S_REC_WAIT_SRR:
			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
	
			if(capmsg.msgOperaCode !=CAP_OC_SpecializedResourceReport)
			{
				if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn)
				{  
					DebugMsg(debugmib.display.asciiOut,"< Error message received >");
				}
			}
			AddPPSStatistics(MIBPPS_SPE_RUS_RPT,shmp->process_info.dir);	
			retval = pin_mng_exit_to_main_menu;		
		break;
	}
	return retval;
}
