Files
ocs/mss/pps/src/main/feeTransfer.c
2025-03-03 11:01:26 +08:00

2351 lines
65 KiB
C

#include "../include/includes.h"
#include "../include/ppsm.h"
#include "../include/ramdata.h"
#include "../include/ppsinf.h"
#include "../include/message.h"
#include "../include/iofunc.h"
#include "../include/version.h"
#include "../include/pps_public.h"
#include "../include/cdrme.h"
#include "../include/param.h"
#include "../include/plat_inc.h"
#include "../../../../plat/scf/src/include/scfmsg.h"
#include "../../../../plat/scf/src/include/scfdef.h"
#include "../include/ppsMibTable.h"
#include "../include/mfunc.h"
#include <stdlib.h>
extern PPSParamStruct ppsParam;
extern struct timeval tvnow;
extern _ram_data *ramshm_ptr;
extern _state_machine *smshm_ptr;;
extern int SendUSSDRequest(u_short portid, char *ussd_info);
extern int smppSendMsg(u_char *peerNumber,u_char *msg,u_char serviceNumPosition);
extern int StuffCapMessage(CapArg capArg, PCAP_Message pcap_message);
extern int ppsDebugCapMsg(CAP_Message *cap_message,int flag);
extern BOOL isPromotionCanBeTransfered(_account_info *accountInfo);
extern BOOL isPromotionFirstTransfered(_account_info *accountInfo);
extern void SendManualOperationCDR(_account_info *caller_info,_account_info *called_info,int charge);
extern int get_transfer_resolution();
extern u_short debug_messages;
extern int logMsgFlag;
static double feeAsciiToFloat(u_char *fee);
ulong getSystemCurrencyResolution();
#define MAX_FEE_LENGTH 7
enum transfeeAccountState
{
S_TRANSFER_IDLE,
S_INPUT_DESTNUMBER,
S_WART_INPUT_DESTNUMBER,
S_INPUT_DESTNUMBER_AGAIN,
S_WART_INPUT_DESTNUMBER_AGAIN,
S_MATCH_DESTNUMBER,
S_DESTNUMBER_NOT_MATCHED,
S_TRANSFER_CHECK_DSTNUMBER,
S_TRANSFER_CHECK_TRANSFERED_FEE,
S_FULL_PARTIAL_TRANSFER_CHOICE,
S_WAIT_FULL_PARTIAL_TRANSFER_CHOICE,
S_INPUT_FEE_TRANSFERED,
S_WAIT_INPUT_FEE_TRANSFERED,
S_PLAY_TRANSFERED_FEE_ERROR,
S_WRONG_INPUT_FEE,
S_TRANSFER_CONFIRM,
S_PLAY_TRANSFER_CONFIRM_SUCCESS,
S_WAIT_TRANSFER_CONFIRM,
S_TRANSFER_PROCESSING,
S_PLAY_TRANSFERED_FEE_SUCCESS,
S_CHECK_USSD_INPUT,
S_USSD_FT_ALL_IN_ONE_INPUT,
S_USSD_FT_REST_START,
S_TRANSFER_EXIT,
};
enum transfer_mode{
FULL_TRANSFER_MODE,
PARTIAL_TRANSFER_MODE,
};
#define changeTransferState(portid,val) do { \
feeTransfer = &shmp->process_info.ppsService.feeTransfer;\
feeTransfer->state = val;\
shmp->process_info.serviceInput = 0;\
shmp->process_info.funnel = 0;\
pps_print_event(shmp->process_info.logMsisdn,"[%05d]\33[32m%s\33[0m transfer to state \33[36m%s\33[0m", portid, __FUNCTION__, #val); \
} while(0)
u8 getTransferState(u_short portid)
{
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
return shmp->process_info.ppsService.feeTransfer.state;
}
void playPromptAndCollectVoice(u_short portid,u_short voiceID,u8 inputLen)
{
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
shmp->process_info.funnel = 0;
shmp->process_info.srfRelease = 0;
shmp->process_info.voiceID = voiceID;
shmp->process_info.maxPCUInfoLen = inputLen;
shmp->process_info.endOfReplyDigit[0] = 1;
shmp->process_info.endOfReplyDigit[1] = 12;
SendPromptAndCollectUserInfo(portid);
}
void playPromptVoice(u_short portid,u_short voiceID)
{
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
shmp->process_info.funnel = 0;
shmp->process_info.srfRelease = 0;
shmp->process_info.voiceID = voiceID;
SendSrfPlayAnnouncement(portid);
}
void clearTransferInfo(u_short portid)
{
_state_data *shmp;
PutLogFunID("clearTransferInfo");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
memset(&shmp->process_info.ppsService.feeTransfer,0,sizeof(TRANSFER_FEE));
}
int WaitingForInput(_state_data *shmp,u8 *inputMsg)
{
int retval = NO_INPUT,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 = INPUT_ERROR_EXIT);
}
pPCUI=&capArg.msg_list.promptAndCollectUserInformationArg;
len = pPCUI->digitsResponse[0];
if(len > MAX_IVR_INPUT_LEN)
len = MAX_IVR_INPUT_LEN;
if(pPCUI->digitsResponse[1] & 0x20)
{
pPCUI->digitsResponse[len] |=0xF0;
}
ppsBcdToAsciiR((char *)inputMsg,&pPCUI->digitsResponse[2],2*(len-1));
StringCut((char *)inputMsg,'F');
retval = INPUT_SUCCESS;
break;
case CAP_O_UABORT:
case CAP_O_PABORT:
default:
retval = INPUT_ERROR_EXIT;
break;
}
return retval;
}
static double asciiFeeToFloat(u_char *feeChar)
{
u_char *pFloat;
double value;
u8 i,len,Btimes = 0;
len = strlen((char *)feeChar);
if(strlen((char *)feeChar) > MAX_FEE_LENGTH)
return -1;
for(i = 0;i < len;i++)
{/* only '0' - '9' and 'B' are allowed */
if(feeChar[i] == 'B')
Btimes++;
if(feeChar[i] < '0' && feeChar[i] > '9' && feeChar[i] != 'B')
return -1;
}
if(Btimes > 1)/* 'B' only one time */
return -1;
if(feeChar[0] == 'B')
return -1;
pFloat = (u_char *)strchr((char *)feeChar,'B');
if(pFloat != NULL)
*pFloat = '.';
value = feeAsciiToFloat(feeChar);
if(value <= 0)
return -1;
return value;
}
ulong getSystemCurrencyResolution()
{
long resolution;
switch(ppsParam.ppsTables.promptResolution[0].currencyResolution)
{
case 0:
resolution = 1;
break;
case 1:
resolution = 10;
break;
case 2:
default:
resolution = 100;
break;
}
return resolution;
}
static int WaitingForInputTransferOutFee(_state_data *shmp)
{
u_char input_msg[64] = {0};
double fee;
ulong resolution = 1;
int result;
PutLogFunID("WaitingForInputTransferOutFee");
memset(input_msg,0,64);
result = WaitingForInput(shmp,input_msg);
if(result != INPUT_SUCCESS)
return result;
fee = asciiFeeToFloat(input_msg);
if(fee <= 0 )
return 2;/* format error */
if(get_transfer_resolution())
resolution = getSystemCurrencyResolution();
shmp->process_info.ppsService.feeTransfer.fee = (int)(fee*resolution);
return result;
}
int WaitingForInputTransferOutAccount(_state_data *shmp)
{
u_char input_msg[64] = {0};
int result;
PutLogFunID("WaitingForInputTransferOutFee");
memset(input_msg,0,64);
if(shmp->process_info.ussd_transfer_one_input_flag ==1 )
{
result = INPUT_SUCCESS;
strcpy((char *)input_msg, shmp->process_info.tmpDigits);
}
else
result = WaitingForInput(shmp,input_msg);
if(result != INPUT_SUCCESS)
return result;
CutUnknownPrefix((char *)input_msg);
if((strlen((char *)input_msg) > MAX_ASCII_NUMBER_LEN)
||!strcmp((char *)shmp->caller_info.number, (char *)input_msg))
{
if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
return (result = INPUT_ERROR_REINPUT);
}
memset(&shmp->called_info,0,sizeof(_account_info));
strcpy((char *)shmp->called_info.number, (char *)input_msg);
if(GetAccountPos(&shmp->called_info) == FALSE)
{
if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
return (result = INPUT_ERROR_REINPUT);
}
if(get_transfer_status_normal_flag())
{
int status = GetAccountStatus(&shmp->called_info);
if(status != T_NORMAL &&
status != T_FRESH &&
status != T_SUSPEND)
{
if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
return (result=INPUT_ERROR_REINPUT);
}
}
return result;
}
void saveFirstInputtedTransferOutAccount(_state_data *shmp)
{
memcpy(&shmp->process_info.ppsService.feeTransfer.account,&shmp->called_info,sizeof(_account_info));
}
int matchTwoInpuutedTransferOutAccount(_state_data *shmp)
{
if(!strcmp((char *)shmp->process_info.ppsService.feeTransfer.account.number, (char *)shmp->called_info.number))
return 1;
return 0;
}
static int WaitForTransferMode(_state_data *shmp)
{
u_char input_msg[64] = {0};
int result;
PutLogFunID("WaitForTransferMode");
memset(input_msg,0,64);
result = WaitingForInput(shmp,input_msg);
if(result != INPUT_SUCCESS)
return result;
if(input_msg[0] < '0' || input_msg[0] > '1')
{
if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
{
return INPUT_ERROR_EXIT;
}
return INPUT_ERROR_REINPUT;
}
shmp->process_info.ppsService.feeTransfer.transferMode = input_msg[0];
return result;
}
static int WaitForChoice(_state_data *shmp)
{
u_char input_msg[64] = {0};
int result;
PutLogFunID("WaitForChoice");
memset(input_msg,0,64);
result = WaitingForInput(shmp,input_msg);
if(result != INPUT_SUCCESS)
return result;
if(input_msg[0] < '0' || input_msg[0] > '3')
{
if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
{
return INPUT_ERROR_EXIT;
}
return INPUT_ERROR_REINPUT;
}
shmp->process_info.ppsService.feeTransfer.transferMode = input_msg[0];
return result;
}
static int WaitForChoice_chargeOrTransfer(_state_data *shmp)
{
u_char input_msg[64] = {0};
int result;
PutLogFunID("WaitForChoice");
memset(input_msg,0,64);
result = WaitingForInput(shmp,input_msg);
if(result != INPUT_SUCCESS)
return result;
if(input_msg[0] < '1' || input_msg[0] > '2')
{
if(shmp->process_info.serviceInput++>=SERVICE_INPUT_NUM)
{
return INPUT_ERROR_EXIT;
}
return INPUT_ERROR_REINPUT;
}
shmp->process_info.ppsService.feeTransfer.transferMode = input_msg[0];
return result;
}
int getInputtedChoice(_state_data *shmp)
{
return shmp->process_info.ppsService.feeTransfer.transferMode - '0';
}
long GetPromotionExpiration(_account_info *ptr)
{
_prepaid_data *shmp=&ramshm_ptr->prepaid_data;
PutLogFunID("GetIncomingExpiration");
return (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) ?
shmp->prepaid_info[ptr->head][ptr->tail].promo_date
: (tvnow.tv_sec+1);
}
float GetPromotion(_account_info *ptr)
{
_prepaid_data *shmp=&ramshm_ptr->prepaid_data;
PutLogFunID("GetIncomingExpiration");
return (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) ?
shmp->prepaid_info[ptr->head][ptr->tail].promo_balance : 0;
}
int checkTransferedPartialFee(_account_info *callerInfo,float feeTransfered)
{
float balance=0;
BOOL balanceExpired=FALSE,promotionExpired=FALSE;
if(isPromotionCanBeTransfered(callerInfo))
{
if(GetExpiration(callerInfo) <= tvnow.tv_sec)
balanceExpired = TRUE;
if(GetPromotionExpiration(callerInfo) <= tvnow.tv_sec)
promotionExpired = TRUE;
if(balanceExpired && promotionExpired)
return CHECK_TRANSFERED_FEE_EXPIERED;
if(!balanceExpired)
balance += GetBalanceWithOutPromotion(callerInfo->head,callerInfo->tail);
if(!promotionExpired)
balance += GetPromotion(callerInfo);
}
else
{
if(GetExpiration(callerInfo) <= tvnow.tv_sec)
return CHECK_TRANSFERED_FEE_EXPIERED;
balance = GetBalanceWithOutPromotion(callerInfo->head,callerInfo->tail);
}
if(balance < feeTransfered || feeTransfered<= 0)
return CHECK_TRANSFERED_FEE_INSUFFIENT;
return CHECK_TRANSFERED_FEE_OK;
}
int GetBalanceWithOutPromotion(int head, int tail)
{
_prepaid_data *shmp=&ramshm_ptr->prepaid_data;
PutLogFunID("getBalanceWithOutPromotion");
if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT)
return shmp->prepaid_info[head][tail].balance;
return FALSE;
}
int checkTransferedFullFee(_state_data *shmp)
{
float balance;
if(GetBalance(&shmp->caller_info) <= 0)
return CHECK_TRANSFERED_FEE_INSUFFIENT;
if(GetExpiration(&shmp->caller_info) < (tvnow.tv_sec+1)
&& GetPromotionExpiration(&shmp->caller_info) < (tvnow.tv_sec+1))
return CHECK_TRANSFERED_FEE_EXPIERED;
if(isPromotionCanBeTransfered(&shmp->caller_info))
{
balance = GetAccountBalance(shmp->caller_info.head,shmp->caller_info.tail);
}
else
{
balance = GetBalanceWithOutPromotion(shmp->caller_info.head,shmp->caller_info.tail);
}
if(balance<=0)
return CHECK_TRANSFERED_FEE_INSUFFIENT;
shmp->process_info.ppsService.feeTransfer.fee = balance;
return CHECK_TRANSFERED_FEE_OK;
}
static int expieredDaysTransfer_not_used(_account_info *callerInfo,_account_info *destInfo,float transferedFee,float promotion)
{
_prepaid_data *prepaidPoint=&ramshm_ptr->prepaid_data;
_prepaid_info *pcalled,*pcaller;
float balance,daysPerBalance,valid_time;
long diff;
COSTable *cosTableItem;
pcalled = &prepaidPoint->prepaid_info[destInfo->head][destInfo->tail];
pcaller = &prepaidPoint->prepaid_info[callerInfo->head][callerInfo->tail];
cosTableItem = &ppsParam.ppsTables.cosTable[pcalled->cos_id%MaxCosTableItem];
if(transferedFee > 0)
{
balance = pcaller->balance;
diff = GetExpiration(callerInfo) - tvnow.tv_sec;
if(balance == 0)
daysPerBalance = 0;
else
daysPerBalance = diff/balance;
valid_time = transferedFee*daysPerBalance;
pcalled->mo_expiration_date = valid_time + pcalled->mo_expiration_date;
if(cosTableItem->accountValidity[0].maxAccountValidityDays<=0)
cosTableItem->accountValidity[0].maxAccountValidityDays = 730;
if(pcalled->mo_expiration_date > tvnow.tv_sec+ cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600)
pcalled->mo_expiration_date = tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600;
}
if(promotion > 0)
{
balance = pcaller->promo_balance;
diff = GetPromotionExpiration(callerInfo) - tvnow.tv_sec;
if(balance == 0)
daysPerBalance = 0;
else
daysPerBalance = diff/balance;
valid_time = promotion*daysPerBalance;
pcalled->promo_date = valid_time + pcalled->promo_date;
if(cosTableItem->accountValidity[0].maxAccountValidityDays<=0)
cosTableItem->accountValidity[0].maxAccountValidityDays = 730;
if(pcalled->promo_date > tvnow.tv_sec+ cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600)
pcalled->promo_date = tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600;
}
return 1;
}
static int expieredDaysTransfer(_account_info *callerInfo,_account_info *destInfo,float transferedFee,float promotion)
{
_prepaid_data *prepaidPoint=&ramshm_ptr->prepaid_data;
_prepaid_info *pcalled,*pcaller;
if(get_not_change_transfer_expiry_date())
{return 1;}
pcalled = &prepaidPoint->prepaid_info[destInfo->head][destInfo->tail];
pcaller = &prepaidPoint->prepaid_info[callerInfo->head][callerInfo->tail];
if(transferedFee > 0)
{
if(pcalled->mo_expiration_date < pcaller->mo_expiration_date)
pcalled->mo_expiration_date = pcaller->mo_expiration_date;
if(pcalled->mt_expiration_date < pcaller->mt_expiration_date)
pcalled->mt_expiration_date = pcaller->mt_expiration_date;
}
if(promotion > 0)
{
if(pcalled->promo_date < pcaller->promo_date)
pcalled->promo_date = pcaller->promo_date;
}
return 1;
}
int poolTransferAccount(_account_info *callerInfo,_account_info *destInfo,float transferedFee)
{ /*Notice: Be sure to call checkTransferedPartialFee() first to check */
u_long instance;
int retval=0;
_prepaid_data *prepaidPoint=&ramshm_ptr->prepaid_data;
_prepaid_info *pcaller,*pcalled;
float diff=0;
double oldCallerBalance,oldCallerPromo,oldCalledBalance,oldCalledPromo;
BOOL balanceExpired=FALSE,promotionExpired=FALSE;
if(transferedFee == 0)
{
//pps_print_error(0,"%s no need to transfer fee:%0.4f to %s",callerInfo->number,transferedFee,destInfo->number);
return -1;
}
pcalled = &prepaidPoint->prepaid_info[destInfo->head][destInfo->tail];
oldCalledBalance = pcalled->balance;
oldCalledPromo = pcalled->promo_balance;
pcaller = &prepaidPoint->prepaid_info[callerInfo->head][callerInfo->tail];
oldCallerBalance = pcaller->balance;
oldCallerPromo = pcaller->promo_balance;
if(isPromotionCanBeTransfered(callerInfo) == FALSE)
{
expieredDaysTransfer(callerInfo,destInfo,transferedFee,0);
pcalled->balance += transferedFee;
pcaller->balance -= transferedFee;
}
else
{
if(GetExpiration(callerInfo) <= tvnow.tv_sec)
balanceExpired = TRUE;
if(GetPromotionExpiration(callerInfo) <= tvnow.tv_sec)
promotionExpired = TRUE;
if(balanceExpired == TRUE)
{
expieredDaysTransfer(callerInfo,destInfo,0,transferedFee);
pcalled->promo_balance += transferedFee;
pcaller->promo_balance -= transferedFee;
}
else if(promotionExpired == TRUE)
{
expieredDaysTransfer(callerInfo,destInfo,transferedFee,0);
pcalled->balance += transferedFee;
pcaller->balance -= transferedFee;
}
else
{
if(isPromotionFirstTransfered(callerInfo) == FALSE)
{
if(transferedFee > pcaller->balance)
{
diff = transferedFee - pcaller->balance;
expieredDaysTransfer(callerInfo,destInfo,transferedFee - diff,diff);
pcalled->balance += transferedFee - diff;
pcaller->balance = 0;
pcalled->promo_balance += diff;
pcaller->promo_balance -= diff;
}
else
{
expieredDaysTransfer(callerInfo,destInfo,transferedFee,0);
pcalled->balance += transferedFee;
pcaller->balance -= transferedFee;
}
}
else if(isPromotionFirstTransfered(callerInfo) == TRUE)
{
if(transferedFee > pcaller->promo_balance)
{
diff = transferedFee - pcaller->promo_balance;
expieredDaysTransfer(callerInfo,destInfo,diff,transferedFee - diff);
pcalled->promo_balance += transferedFee - diff;
pcaller->promo_balance = 0;
pcalled->balance += diff;
pcaller->balance -= diff;
}
else
{
expieredDaysTransfer(callerInfo,destInfo,0,transferedFee);
pcalled->promo_balance += transferedFee;
pcaller->promo_balance -= transferedFee;
}
}
}
}
UpdateAccountStatus(destInfo->head, destInfo->tail, T_NORMAL);
instance = destInfo->head * UNIT_STORE_ACCOUNT + destInfo->tail;
if(pcalled->balance >= 0)
{
UpdateAccountOverdraft(destInfo->head, destInfo->tail, 0);
}
resetCMBTimes(destInfo);
SendAccountRealSync(instance,
(pcalled->balance-oldCalledBalance),
(pcalled->promo_balance-oldCalledPromo),
OMC_OCODE_EDIT);
instance = callerInfo->head * UNIT_STORE_ACCOUNT + callerInfo->tail;
SendAccountRealSync(instance,
(pcaller->balance-oldCallerBalance),
(pcaller->promo_balance-oldCallerPromo),
OMC_OCODE_EDIT);
return (retval = 1);
}
void notifyUserTransferResult(_state_data *shmp,u8 callerOrCalled)
{
u_char msgSend[MAX_SMS_LEN*4] = {0}, /*tmpbuf[64]={0},*/ buf[MAX_SMS_LEN*2]={0};
float balance;
//u_char expire_date[128]={0},promotion_expire_date[128]={0};
//int i,j;
u_char dayTimeReadable[32]={0};
char tmpCaller[32],tmpCalled[32];
balance = shmp->process_info.ppsService.feeTransfer.fee;
if(balance == 0)
{
pps_print_error(shmp->process_info.logMsisdn,"[%05d]No need to notify transfer result,fee:%0.4f",shmp->process_info.portid,balance);
return;
}
ppsgetdaytime_readFormat((char *)dayTimeReadable);
switch(callerOrCalled)
{
case NOTIFY_CALLER:
strcpy((char *)msgSend, (char *)getSmsSentenceNative(0, SMS_TRANSFERED_OUT));
break;
case NOTIFY_CALLED:
default:
strcpy((char *)msgSend, (char *)getSmsSentenceNative(0,SMS_TRANSFERED_IN));
break;
}
fillMoneyToContent(balance, (char *)buf);
strcat((char *)msgSend, (char *)buf);
switch(callerOrCalled)
{
case NOTIFY_CALLER:
strcpy(tmpCaller, (char *)shmp->process_info.ppsService.feeTransfer.account.number);
strcpy(tmpCalled, (char *)shmp->caller_info.number);
cliManipulationFunction(tmpCaller,tmpCalled);
sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0,SMS_TO), tmpCaller);
sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0,SMS_ON), dayTimeReadable);
{
char tmp_info[256];
GetAccountPromptInfo(&shmp->caller_info, tmp_info);
strcat((char *)msgSend, tmp_info);
smppSendMsg(shmp->caller_info.number,msgSend,FeeTransferPosition);
}
/*
smppSendMsg(shmp->caller_info.number,msgSend,FeeTransferPosition);
i = shmp->caller_info.head%MSISDN_HEAD_NUM;
j = shmp->caller_info.tail%UNIT_STORE_ACCOUNT;
AsciiTime(expire_date,ramshm_ptr->prepaid_data.prepaid_info[i][j].mo_expiration_date);
AsciiTime(promotion_expire_date,ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_date);
smppSendAccountInfo(shmp->caller_info.number,
ppsParam.ppsTables.serviceNumber[FeeTransferPosition].number,
(long)ramshm_ptr->prepaid_data.prepaid_info[i][j].balance,expire_date,
(long)ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_balance,promotion_expire_date,
0,"","",
ramshm_ptr->prepaid_data.prepaid_info[i][j].language_type );
*/
break;
case NOTIFY_CALLED:
default:
strcpy(tmpCaller, (char *)shmp->caller_info.number);
strcpy(tmpCalled, (char *)shmp->process_info.ppsService.feeTransfer.account.number);
cliManipulationFunction(tmpCaller,tmpCalled);
sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0, SMS_FROM), tmpCaller);
sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0, SMS_ON), dayTimeReadable);
{
char tmp_info[256];
GetAccountPromptInfo(&shmp->process_info.ppsService.feeTransfer.account, tmp_info);
strcat((char *)msgSend, tmp_info);
smppSendMsg(shmp->process_info.ppsService.feeTransfer.account.number,msgSend,FeeTransferPosition);
}
/*
smppSendMsg(shmp->process_info.ppsService.feeTransfer.account.number,msgSend,FeeTransferPosition);
i = shmp->process_info.ppsService.feeTransfer.account.head;
j = shmp->process_info.ppsService.feeTransfer.account.tail;
AsciiTime(expire_date,ramshm_ptr->prepaid_data.prepaid_info[i][j].mo_expiration_date);
AsciiTime(promotion_expire_date,ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_date);
smppSendAccountInfo(shmp->process_info.ppsService.feeTransfer.account.number,
ppsParam.ppsTables.serviceNumber[FeeTransferPosition].number,
(long)ramshm_ptr->prepaid_data.prepaid_info[i][j].balance,expire_date,
(long)ramshm_ptr->prepaid_data.prepaid_info[i][j].promo_balance,promotion_expire_date,
0,"","",
ramshm_ptr->prepaid_data.prepaid_info[i][j].language_type);
*/
break;
}
}
void notifyUserTransferResult_1(_account_info *srcUsr, _account_info *dstUsr, int amount, u8 callerOrCalled)
{
u_char msgSend[MAX_SMS_LEN*4] = {0}, /*tmpbuf[64]={0}, */buf[MAX_SMS_LEN*2]={0};
float balance;
//u_char expire_date[128]={0},promotion_expire_date[128]={0};
//int i,j;
u_char dayTimeReadable[32]={0};
char tmpCaller[32],tmpCalled[32];
balance = amount;
if(balance == 0.0)
{
return;
}
ppsgetdaytime_readFormat((char *)dayTimeReadable);
switch(callerOrCalled)
{
case NOTIFY_CALLER:
strcpy((char *)msgSend, (char *)getSmsSentenceNative(0,SMS_TRANSFERED_OUT));
break;
case NOTIFY_CALLED:
default:
strcpy((char *)msgSend, (char *)getSmsSentenceNative(0,SMS_TRANSFERED_IN));
break;
}
fillMoneyToContent(balance, (char *)buf);
strcat((char *)msgSend, (char *)buf);
switch(callerOrCalled)
{
case NOTIFY_CALLER:
strcpy(tmpCaller, (char *)dstUsr->number);
strcpy(tmpCalled, (char *)srcUsr->number);
cliManipulationFunction(tmpCaller, tmpCalled);
sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0,SMS_TO), tmpCaller);
sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0,SMS_ON), dayTimeReadable);
{
char tmp_info[256];
GetAccountPromptInfo(srcUsr, tmp_info);
strcat((char *)msgSend, tmp_info);
smppSendMsg(srcUsr->number, msgSend, FeeTransferPosition);
}
break;
case NOTIFY_CALLED:
default:
strcpy(tmpCaller, (char *)srcUsr->number);
strcpy(tmpCalled, (char *)dstUsr->number);
cliManipulationFunction(tmpCaller, tmpCalled);
sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0, SMS_FROM), tmpCaller);
sprintf((char *)msgSend+strlen((char *)msgSend), " %s %s", getSmsSentenceNative(0, SMS_ON), dayTimeReadable);
{
char tmp_info[256];
GetAccountPromptInfo(dstUsr, tmp_info);
strcat((char *)msgSend, tmp_info);
smppSendMsg(dstUsr->number, msgSend, FeeTransferPosition);
}
break;
}
}
void SendTransferCDR(_account_info *caller_info,_account_info *called_info,float charge)
{
_tocdr_report pcdr;
char buf[BUFSIZE]={""};
int fee,balance,len;
int head, tail;
PutLogFunID("SendManualOperationCDR");
head = caller_info->head;
tail = caller_info->tail;
memset(&pcdr, 0, sizeof(_tocdr_report));
if (charge > 0)
{
pcdr.type[0] = CT_TRANFER_IN;
pcdr.type[1] = CT_TRANFER_IN>>8;
}
else if (charge < 0)
{
pcdr.type[0] = CT_TRANFER_OUT;
pcdr.type[1] = CT_TRANFER_OUT>>8;
}
else
{
//pps_print_error(0,"transfee fee is %d,%s no need to send cdr at %s",
// charge,caller_info->number,__FUNCTION__);
return ;
}
AsciiToBcd(pcdr.seizuretime, ppsgetdaytime(buf), 14);
AsciiToBcd(pcdr.answertime, ppsgetdaytime(buf), 14);
AsciiToBcd(pcdr.releasetime, ppsgetdaytime(buf), 14);
pcdr.duration[0] = 0;
fee = (int)charge;
fee = abs(fee);
memcpy(pcdr.charge,&fee,4);
balance = (int) GetAccountBalance(head, tail);
memcpy(pcdr.balance,&balance,4);
GetAccountMsisdn(head,tail,&pcdr.msisdn[1]);
ByteRev(pcdr.msisdn,9,0);
pcdr.msisdn[0]=0x91;
memcpy(pcdr.caller,pcdr.msisdn,9);
buf[0] = 0;
pcdr.called[0] = 0x91;
len = strlen((char *)called_info->number)%20;
ppsAsciiToBcdR(&pcdr.called[1], (char *)called_info->number,(len+1)/2*2);
if(len %2)
{
pcdr.called[(len+1)/2] |= 0xF0;
}
if(len<21)
{
pcdr.called[(len+1)/2+1] = 0xFF;
}
sprintf(buf,"FFFFFFFFFFFFFFFFFF");
AsciiToBcd(pcdr.imsi,buf,16);
pcdr.tcos[0] = NORMAL_CLEARING%256;
CDRStatistics(&pcdr,charge, 0);
StoreCDR(&pcdr);
pps_real_update_user_file(head, tail);
#if DEBUG
if((logMsgFlag & 0x04) || (logMsgFlag & 0x02))
DebugMsg(debugmib.display.asciiOut, "SendTransferCDR");
#endif
}
static void sendTransferInCDR(_state_data *shmp)
{
float charge;
charge = shmp->process_info.ppsService.feeTransfer.fee;
SendTransferCDR(&shmp->process_info.ppsService.feeTransfer.account,&shmp->caller_info,charge);
}
static void sendTransferOutCDR(_state_data *shmp)
{
float charge;
charge = shmp->process_info.ppsService.feeTransfer.fee;
SendTransferCDR(&shmp->caller_info,&shmp->process_info.ppsService.feeTransfer.account,-charge);
}
void FeeTransferTransaction(_state_data *shmp)
{
poolTransferAccount(&shmp->caller_info,
&shmp->process_info.ppsService.feeTransfer.account,
shmp->process_info.ppsService.feeTransfer.fee);
notifyUserTransferResult(shmp,NOTIFY_CALLER);
notifyUserTransferResult(shmp,NOTIFY_CALLED);
sendTransferInCDR(shmp);
sendTransferOutCDR(shmp);
}
int SendTransferInfoPromptToSrf(u_short portid)
{
int balance,centbalance,hth_b,th_b,h_b,b_b;
char expire_date[20]="",buf[BUFSIZE]="";
int resolution=100;
int len;
_state_data *shmp;
int dlgid,invokeid=0;
CAP_Message cap_message;
CapArg capArg;
CapPlayAnnouncement *pPlayAnnouncement;
CapMessageID *pMID;
u8 transferNumber[MAX_MSISDN_BLEN];
u8 varIndex = 0;
PutLogFunID("SendTransferInfoPromptToSrf");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir);
balance = shmp->process_info.ppsService.feeTransfer.fee;
if(balance < 0)
balance = 0;
AsciiTime(expire_date,GetExpiration(&shmp->caller_info));
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;
resolution = getSystemCurrencyResolution();
centbalance = (balance % resolution);
balance = (balance / resolution);
hth_b = (balance / 10000)%100;
th_b = (balance / 1000)%10;
h_b = (balance / 100)%10;
b_b = (balance % 100);
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;
pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID;
pMID->variableMessage.elementaryMessageID =
GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 +
INPUT_TRANSFER_CONFIRM;
pMID->variableMessage.variableParts.num = 2;
pMID->variableMessage.variableParts.variablePart[varIndex].choice_id = 4;
sprintf(buf,"%02d",hth_b);
ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[varIndex].price[0],
buf,2);
sprintf(buf,"%d%d",th_b,h_b);
ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[varIndex].price[1],
buf,2);
sprintf(buf,"%02d",b_b);
ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[varIndex].price[2],
buf,2);
sprintf(buf,"%02d",centbalance);
ppsAsciiToBcdR(&pMID->variableMessage.variableParts.variablePart[varIndex].price[3],
buf,2);
varIndex++;
len = strlen((char *)shmp->process_info.ppsService.feeTransfer.account.number);
ppsAsciiToBcdR(transferNumber, (char *)shmp->process_info.ppsService.feeTransfer.account.number, len);
if(len>(MAX_MSISDN_BLEN-1)*2)
len = (MAX_MSISDN_BLEN - 1 )*2;
pMID->variableMessage.variableParts.variablePart[varIndex].choice_id = 1;
pMID->variableMessage.variableParts.variablePart[varIndex].number[0] = (len+1)/2+1;
if(len%2==0)
{
pMID->variableMessage.variableParts.variablePart[varIndex].number[1] = 0x04;
memcpy(&pMID->variableMessage.variableParts.variablePart[varIndex].number[2],
transferNumber,
(len+1)/2);
}
else
{
pMID->variableMessage.variableParts.variablePart[varIndex].number[1] = 0x24;
memcpy(&pMID->variableMessage.variableParts.variablePart[varIndex].number[2],
transferNumber,
(len+1)/2);
pMID->variableMessage.variableParts.variablePart[varIndex].number[2+(len+1)/2] &=0x0F;
}
pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07;
pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01;
pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00;
pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x00;
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
return 1;
}
int getUssdACK_old(u_short portid,u_char *ussd_data)
{
MapOprSrv_struct opr_srv;
u8 data_flow[256];
struct MapPUSSR_Arg *pussr_arg;
_state_data *shmp = (_state_data *) smshm_ptr->state_data;
if(portid>=MAX_FSM_PROCESS)
{
return -1;
}
shmp += (portid);
if(!map_get_oprdata(data_flow,shmp->context_info.map_did))
{
return 0;
}
if((data_flow[9] != UnstrctSSReq) || data_flow[1]<14)
{
if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn)
{
DebugMsg(debugmib.display.asciiOut,
"\n\33[31m portid: %d ,did: %d, wait USSDR_ACK but %d received\33[0m",
portid,shmp->context_info.map_did,data_flow[9]);
}
pps_send_map_close(portid);
return -1;
}
if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn)
{
DebugMsg(debugmib.display.asciiOut,
"\nportid: %d ,did: %d, Get Map opr,type:<%d>, PUSSR ",
portid,shmp->context_info.map_did,
data_flow[9]);
pps_debug_map_msg(data_flow,0);
}
opr_srv.version = shmp->context_info.acn_ver;
opr_srv.message_type = data_flow[9];
opr_srv.message_flag = data_flow[10];
opr_srv.port_id = portid;
opr_srv.dialogue_id = shmp->context_info.map_did;
if(extract_mapparam(&opr_srv,
data_flow[9],
data_flow[10],
data_flow[14]*256+data_flow[15],
&data_flow[16])<=0)
{
if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn)
{
DebugMsg(debugmib.display.asciiOut,
"\n\33[31mportid: %d ,did: %d, decode PUSSR failed \33[0m",
portid,shmp->context_info.map_did);
}
return -1;
}
//shmp->context_info.invoke_id = data_flow[11];
pussr_arg = &opr_srv.msg_list.pussr_arg;
if(pussr_arg->param_flag != 0x01)
{
if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn)
{
DebugMsg(debugmib.display.asciiOut,
"\n\33[31mportid: %d ,did: %d, decode ussd failed,no content,param flag:%d \33[0m",
portid,shmp->context_info.map_did,pussr_arg->param_flag);
}
return -1;
}
switch(pussr_arg->ussd_arg.ussd_scheme & 0x0f)
{
case 0x00:
case 0x0f: /* 7bit */
smppDecodeSM((char *)pussr_arg->ussd_arg.ussd_string.ussd_data,
(char *)ussd_data,
pussr_arg->ussd_arg.ussd_string.string_len);
break;
case 0x04: /* 8bit */
default:
memcpy(ussd_data,
pussr_arg->ussd_arg.ussd_string.ussd_data,
pussr_arg->ussd_arg.ussd_string.string_len);
break;
}
if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn)
{
DebugMsg(debugmib.display.asciiOut,
"\nportid: %d ,did: %d, USSD data: \r\n\%s ",
portid,shmp->context_info.map_did,
ussd_data);
}
return strlen((char *)ussd_data);
}
int getUssdACK(u_short portid,u_char *ussd_data)
{
MapOprSrv_struct opr_srv;
u8 data_flow[256];
struct MapUSSR_Res *ussr_ack;
_state_data *shmp = (_state_data *) smshm_ptr->state_data;
if(portid>=MAX_FSM_PROCESS)
{
return -1;
}
shmp += (portid);
if(!map_get_oprdata(data_flow,shmp->context_info.map_did))
{
return 0;
}
if((data_flow[9] != UnstrctSSReq) || data_flow[1]<14)
{
if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn)
{
DebugMsg(debugmib.display.asciiOut,
"\n\33[31m portid: %d ,did: %d, wait USSDR_ACK but %d received\33[0m",
portid,shmp->context_info.map_did,data_flow[9]);
}
pps_send_map_close(portid);
return -1;
}
if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn)
{
DebugMsg(debugmib.display.asciiOut,
"\nportid: %d ,did: %d, Get Map opr,type:<%d>, USSR ",
portid,shmp->context_info.map_did,
data_flow[9]);
pps_debug_map_msg(data_flow,0);
}
opr_srv.version = shmp->context_info.acn_ver;
opr_srv.message_type = data_flow[9];
opr_srv.message_flag = data_flow[10];
opr_srv.port_id = portid;
opr_srv.dialogue_id = shmp->context_info.map_did;
if(extract_mapparam(&opr_srv,
data_flow[9],
data_flow[10],
data_flow[14]*256+data_flow[15],
&data_flow[16])<=0)
{
if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn)
{
DebugMsg(debugmib.display.asciiOut,
"\n\33[31mportid: %d ,did: %d, decode USSR_ACK failed \33[0m",
portid,shmp->context_info.map_did);
}
return -1;
}
ussr_ack = &opr_srv.msg_list.ussr_res;
if(ussr_ack->param_flag != 0x01)
{
if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn)
{
DebugMsg(debugmib.display.asciiOut,
"\n\33[31mportid: %d ,did: %d, USSR error received,no content,param flag is:%d \33[0m",
portid,shmp->context_info.map_did,ussr_ack->param_flag);
}
return -1;
}
switch(ussr_ack->ussd_res.ussd_scheme & 0x0f)
{
case 0x00:
case 0x0f: /* 7bit */
smppDecodeSM((char *)ussr_ack->ussd_res.ussd_string.ussd_data,
(char *)ussd_data,
ussr_ack->ussd_res.ussd_string.string_len);
if(ussr_ack->ussd_res.ussd_string.string_len %7 == 0)
{
int tmplen;
tmplen = ussr_ack->ussd_res.ussd_string.string_len*8/7;
if(ussd_data[tmplen-1] == 0x0d) /* ussd padding byte: 0x0d */
{
ussd_data[tmplen-1] = '\0';
}
}
break;
case 0x04: /* 8bit */
default:
memcpy(ussd_data,
ussr_ack->ussd_res.ussd_string.ussd_data,
ussr_ack->ussd_res.ussd_string.string_len);
break;
}
if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn)
{
DebugMsg(debugmib.display.asciiOut,
"\nportid: %d ,did: %d, USSD data: \r\n\%s ",
portid,shmp->context_info.map_did,
ussd_data);
}
return strlen((char *)ussd_data);
}
int SendServiceNotApplied(u_short portid,u8 ussdSmsFlag,u8 serviceNumberPosition)
{
u_char tmp[MAX_SMS_LEN*4] = {0};
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_SERVICE_NOT_APPLIED));
switch(ussdSmsFlag)
{
case USSD_TRANSFER:
//SendUSSDRequest(portid,tmp);
SendUSSDNotify(portid, (char *)tmp);
break;
case SMS_TRANSFER:
default:
smppSendMsg(shmp->caller_info.number,tmp,serviceNumberPosition);
break;
}
return 1;
}
static int SendTransferRequest(u_short portid,u8 ussdSmsFlag)
{
u_char tmp[MAX_SMS_LEN*4] = {0};
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_TRANSFER_PROMPT));
switch(ussdSmsFlag)
{
case USSD_TRANSFER:
SendUSSDRequest(portid, (char *)tmp);
break;
case SMS_TRANSFER:
default:
smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition);
break;
}
return 1;
}
static int SendReinputTransferRequest(u_short portid,u8 ussdSmsFlag)
{
u_char tmp[MAX_SMS_LEN*4] = {0};
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_FORMAT_ERROR));
strcat((char *)tmp, (char *)getSmsSentenceNative(0,SMS_TRANSFER_PROMPT));
switch(ussdSmsFlag)
{
case USSD_TRANSFER:
SendUSSDRequest(portid, (char *)tmp);
break;
case SMS_TRANSFER:
default:
smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition);
break;
}
return 1;
}
static int SendTransferDstNumberErrorRequest(u_short portid,u8 ussdSmsFlag)
{
u_char tmp[MAX_SMS_LEN*4] = {0};
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_INVALID_NUMBER));
if(shmp->process_info.ussd_transfer_one_input_flag != 1)
{
strcat((char *)tmp, (char *)getSmsSentenceNative(0,SMS_TRANSFER_PROMPT));
}
switch(ussdSmsFlag)
{
case USSD_TRANSFER:
if(shmp->process_info.ussd_transfer_one_input_flag == 1)
SendUSSDNotify(portid, (char *)tmp);
else
SendUSSDRequest(portid, (char *)tmp);
break;
case SMS_TRANSFER:
default:
smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition);
break;
}
return 1;
}
static int SendTransferInsufficientFeeRequest(u_short portid,u8 ussdSmsFlag)
{
u_char tmp[MAX_SMS_LEN*4] = {0};
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_INSUFFICIENT_FEE));
if(shmp->process_info.ussd_transfer_one_input_flag != 1)
{
strcat((char *)tmp, (char *)getSmsSentenceNative(0,SMS_TRANSFER_PROMPT));
}
switch(ussdSmsFlag)
{
case USSD_TRANSFER:
if(shmp->process_info.ussd_transfer_one_input_flag == 1)
SendUSSDNotify(portid, (char *)tmp);
else
SendUSSDRequest(portid, (char *)tmp);
break;
case SMS_TRANSFER:
default:
smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition);
break;
}
return 1;
}
static int SendTransferExpiredAccountRequest(u_short portid,u8 ussdSmsFlag)
{
u_char tmp[MAX_SMS_LEN*4] = {0};
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_EXPIRED_ACCOUNT));
switch(ussdSmsFlag)
{
case USSD_TRANSFER:
SendUSSDRequest(portid, (char *)tmp);
break;
case SMS_TRANSFER:
default:
smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition);
break;
}
return 1;
}
static int SendTransferInfoConfirmRequest(u_short portid,u8 ussdSmsFlag)
{
_state_data *shmp;
//TRANSFER_FEE *transferInfo;
float balance;
u_char tmp[MAX_SMS_LEN*4] = {0}, /*tmpbuf[64]={0}, */buf[MAX_SMS_LEN*2]={0};
char tmpCaller[32],tmpCalled[32];
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
//transferInfo = &shmp->process_info.ppsService.feeTransfer;
strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_WILL_TRANSFER_OUT));
balance = shmp->process_info.ppsService.feeTransfer.fee;
fillMoneyToContent(balance, (char *)buf);
strcat((char *)tmp, (char *)buf);
strcpy(tmpCaller, (char *)shmp->process_info.ppsService.feeTransfer.account.number);
strcpy(tmpCalled, (char *)shmp->caller_info.number);
cliManipulationFunction(tmpCaller,tmpCalled);
sprintf((char *)tmp+strlen((char *)tmp), " %s %s.", getSmsSentenceNative(0,SMS_TO), tmpCaller);
strcat((char *)tmp, (char *)getSmsSentenceNative(0,SMS_YES_OR_NO));
switch(ussdSmsFlag)
{
case USSD_TRANSFER:
SendUSSDRequest(portid, (char *)tmp);
break;
case SMS_TRANSFER:
default:
smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition);
break;
}
return 1;
}
static int SendReinputTransferConfrimRequest(u_short portid,u8 ussdSmsFlag)
{
u_char tmp[MAX_SMS_LEN*4] = {0};
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_FORMAT_ERROR));
strcat((char *)tmp, (char *)getSmsSentenceNative(0,SMS_YES_OR_NO));
switch(ussdSmsFlag)
{
case USSD_TRANSFER:
SendUSSDRequest(portid, (char *)tmp);
break;
case SMS_TRANSFER:
default:
smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition);
break;
}
return 1;
}
int SendTransferSuccessRequest(u_short portid,u8 ussdSmsFlag)
{
u_char tmp[MAX_SMS_LEN*4] = {0};
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
strcpy((char *)tmp, (char *)getSmsSentenceNative(0,SMS_TRANSFER_SUCCESS));
switch(ussdSmsFlag)
{
case USSD_TRANSFER:
SendPSSREnd(portid, (char *)tmp);
//SendUSSDRequest(portid, (char *)tmp);
break;
case SMS_TRANSFER:
default:
smppSendMsg(shmp->caller_info.number,tmp,FeeTransferPosition);
break;
}
return 1;
}
static double feeAsciiToFloat(u_char *fee)
{
u_char *p;
float factor=0.1001;
double value=0;
if(fee == NULL)
return 0;
p = fee;
while(isdigit(*p))
{
value = value*10+(*p-'0');
p++;
}
if(*p == '.')
{
p++;
while(isdigit(*p))
{
value += factor*(*p-'0');
p++;
factor *= 0.1001;
}
}
return value;
}
int getTransferInfo(u_short portid,u_char *ussd_data)
{/* format:number#amount */
_state_data *shmp;
TRANSFER_FEE *transferInfo;
u8 i,len,Btimes = 0,Atimes = 0,Bposition,Aposition,resolution = 1;
u8 *p,feeAscii[64]={0};
double fee;
PutLogFunID("getTransferInfo");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
len = strlen((char *)ussd_data);
for(i = 0;i < len;i++)
{
if(!isdigit(ussd_data[i])
&& ussd_data[i] != '#'
&& ussd_data[i] != '*'
&& ussd_data[i] != '.')
return -1;
if(ussd_data[i] == '#')
{
Btimes++;
Bposition = i;
}
if(ussd_data[i] == '*' || ussd_data[i] == '.')
{
Atimes++;
Aposition = i;
}
}
if(Btimes != 1 || Atimes > 1)
return -1;
if(!isdigit(ussd_data[0]) || !isdigit(ussd_data[len - 1]))
return -1;
if(Atimes >= 1)
{
if(Bposition >= Aposition)
return -1;
}
p = (u8 *)strchr((char *)ussd_data+1, '#');
if(p == NULL)
return -1;
if(!isdigit(*(p+1)))
return -1;
transferInfo = &shmp->process_info.ppsService.feeTransfer;
*p = 0;
memset(feeAscii,0,64);
strcpy((char *)feeAscii, (char *)p+1);
p = (u8 *)strchr((char *)feeAscii, '*');
if(p != NULL)
{
*p = '.';
}
if(strlen((char *)feeAscii) > MAX_FEE_LENGTH)
return -1;
if(get_transfer_resolution())
resolution = getSystemCurrencyResolution();
fee = feeAsciiToFloat(feeAscii);
transferInfo->fee = (int)(fee*resolution);
if(transferInfo->fee <= 0)
return -1;
CutUnknownPrefix((char *)ussd_data);
if(strlen((char *)ussd_data) > MAX_ASCII_NUMBER_LEN)
return -1;
memset(transferInfo->account.number,0,MAX_ASCII_NUMBER_LEN);
strcpy((char *)transferInfo->account.number, (char *)ussd_data);
return 1;
}
int smppSendMsg(u_char *peerNumber,u_char *msg,u_char serviceNumPosition)
{
//u_char buf[256]={0};
//int result = 0;
PutLogFunID("smppSendMsg");
return smppSendMOSM((char *)peerNumber, (char *)ppsParam.ppsTables.serviceNumber[serviceNumPosition].number
, msg, strlen((char *)msg), 0);
}
int saveTransferSMSACK(u_short portid,u_char *sms)
{
_state_data *shmp;
u8 len;
PutLogFunID("saveSMSACK");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
len = strlen((char *)sms) % MAX_INPUT_SMS;
memcpy(shmp->process_info.ppsService.feeTransfer.inputSMS,sms,len);
shmp->process_info.ppsService.feeTransfer.inputSMS[len] = 0;
shmp->process_info.ppsService.feeTransfer.smsTrigger = TRUE;
return len;
}
static int getTransferSMSACK(u_short portid,u_char *sms)
{
_state_data *shmp;
PutLogFunID("getSMSACK");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
if(shmp->process_info.ppsService.feeTransfer.smsTrigger == FALSE)
return 0;
shmp->process_info.ppsService.feeTransfer.smsTrigger = FALSE;
strcpy((char *)sms, (char *)shmp->process_info.ppsService.feeTransfer.inputSMS);
return strlen((char *)sms);
}
static BOOL checkTransferDestNumber(u_short portid)
{
_state_data *shmp;
PutLogFunID("checkTransferDestNumber");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
CutUnknownPrefix((char *)shmp->process_info.ppsService.feeTransfer.account.number);
if(!strcmp((char *)shmp->caller_info.number, (char *)shmp->process_info.ppsService.feeTransfer.account.number))
{
return FALSE;
}
if(GetAccountPos(&shmp->process_info.ppsService.feeTransfer.account)==FALSE)
return FALSE;
if(get_transfer_status_normal_flag())
{
int status = GetAccountStatus(&shmp->process_info.ppsService.feeTransfer.account);
if(status == T_NORMAL ||
status == T_FRESH ||
status == T_SUSPEND)
return TRUE;
else
return FALSE;
}
return TRUE;
}
int transferAccountSMSProc(u_short portid)
{
_state_data *shmp;
u_char short_message[256];
int result = 0;
TRANSFER_FEE *feeTransfer;
PutLogFunID("transferAccountSMSProc");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
switch(getTransferState(portid))
{
case S_TRANSFER_IDLE:
if(isTransferAllowed(portid) == FALSE)
{
SendServiceNotApplied(portid,SMS_TRANSFER,FeeTransferPosition);
changeTransferState(portid,S_TRANSFER_EXIT);
return SERVICE_RETURN_TO_PARENT;
}
result = checkTransferedPartialFee(&shmp->caller_info,1.0);
if(result == CHECK_TRANSFERED_FEE_INSUFFIENT )
{
SendTransferInsufficientFeeRequest(portid,SMS_TRANSFER);
return SERVICE_EXIT_PPS;
}
changeTransferState(portid,S_WART_INPUT_DESTNUMBER);
case S_WART_INPUT_DESTNUMBER:
result = getTransferSMSACK(portid,short_message);
switch(result)
{
case 0:
break;
case -1:
return SERVICE_EXIT_PPS;
break;
default:
short_message[result] = 0;
result = getTransferInfo(portid,short_message);
if(result < 0)
{
SendReinputTransferRequest(portid,SMS_TRANSFER);
return SERVICE_EXIT_PPS;
}
else
changeTransferState(portid,S_TRANSFER_CHECK_TRANSFERED_FEE);
break;
}
case S_TRANSFER_CHECK_TRANSFERED_FEE:
result = checkTransferedPartialFee(&shmp->caller_info,shmp->process_info.ppsService.feeTransfer.fee);
switch(result)
{
case CHECK_TRANSFERED_FEE_INSUFFIENT:
SendTransferInsufficientFeeRequest(portid,SMS_TRANSFER);
return SERVICE_EXIT_PPS;
break;
case CHECK_TRANSFERED_FEE_EXPIERED:
SendTransferExpiredAccountRequest(portid,SMS_TRANSFER);
return SERVICE_EXIT_PPS;
break;
case CHECK_TRANSFERED_FEE_OK:
default:
changeTransferState(portid,S_TRANSFER_CHECK_DSTNUMBER);
break;
}
case S_TRANSFER_CHECK_DSTNUMBER:
if(checkTransferDestNumber(portid) == FALSE)
{
SendTransferDstNumberErrorRequest(portid,SMS_TRANSFER);
return SERVICE_EXIT_PPS;
}
else
changeTransferState(portid,S_TRANSFER_PROCESSING);/* skip confirm */
case S_TRANSFER_PROCESSING:
FeeTransferTransaction(shmp);
changeTransferState(portid,S_TRANSFER_EXIT);
case S_TRANSFER_EXIT:
clearTransferInfo(portid);
return SERVICE_RETURN_TO_PARENT;
break;
}
return SERVICE_KEEP_STATE;
}
int transferAccountUSSDProc(u_short portid)
{
_state_data *shmp;
u_char ussd_data[256]={0};
int result = 0;
TRANSFER_FEE *feeTransfer;
PutLogFunID("transferAccountUSSDProc");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
switch(getTransferState(portid))
{
case S_TRANSFER_IDLE:
if(pps_get_adaptor_flag())
{
changeTransferState(portid,S_USSD_FT_REST_START);
break;
}
if(isTransferAllowed(portid) == FALSE)
{
SendServiceNotApplied(portid,USSD_TRANSFER,FeeTransferPosition);
changeTransferState(portid,S_TRANSFER_EXIT);
break;
}
result = checkTransferedPartialFee(&shmp->caller_info,1.0);
if(result == CHECK_TRANSFERED_FEE_INSUFFIENT)
{
SendTransferInsufficientFeeRequest(portid,USSD_TRANSFER);
return SERVICE_EXIT_PPS;
}
if(shmp->process_info.ussd_transfer_one_input_flag == 1)
{
changeTransferState(portid,S_USSD_FT_ALL_IN_ONE_INPUT);
break;
}
clearTransferInfo(portid);
SendTransferRequest(portid,USSD_TRANSFER);
changeTransferState(portid,S_WART_INPUT_DESTNUMBER);
break;
case S_WART_INPUT_DESTNUMBER:
result = getUssdACK(portid,ussd_data);
switch(result)
{
case 0:
break;
case -1:
return SERVICE_EXIT_PPS;
break;
default:
result = getTransferInfo(portid,ussd_data);
if(result < 0)
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
return SERVICE_EXIT_PPS;
SendReinputTransferRequest(portid,USSD_TRANSFER);
}
else
changeTransferState(portid,S_TRANSFER_CHECK_TRANSFERED_FEE);
break;
}
break;
case S_TRANSFER_CHECK_TRANSFERED_FEE:
result = checkTransferedPartialFee(&shmp->caller_info,shmp->process_info.ppsService.feeTransfer.fee);
switch(result)
{
case CHECK_TRANSFERED_FEE_INSUFFIENT:
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
{
return SERVICE_EXIT_PPS;
}
SendTransferInsufficientFeeRequest(portid,USSD_TRANSFER);
changeTransferState(portid,S_WART_INPUT_DESTNUMBER);
break;
case CHECK_TRANSFERED_FEE_EXPIERED:
SendTransferExpiredAccountRequest(portid,USSD_TRANSFER);
return SERVICE_EXIT_PPS;
break;
case CHECK_TRANSFERED_FEE_OK:
default:
changeTransferState(portid,S_TRANSFER_CHECK_DSTNUMBER);
break;
}
break;
case S_TRANSFER_CHECK_DSTNUMBER:
if(checkTransferDestNumber(portid) == FALSE)
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
{
return SERVICE_EXIT_PPS;
}
SendTransferDstNumberErrorRequest(portid,USSD_TRANSFER);
changeTransferState(portid,S_WART_INPUT_DESTNUMBER);
}
else
changeTransferState(portid,S_TRANSFER_CONFIRM);
break;
case S_TRANSFER_CONFIRM:
SendTransferInfoConfirmRequest(portid,USSD_TRANSFER);
changeTransferState(portid,S_WAIT_TRANSFER_CONFIRM);
break;
case S_WAIT_TRANSFER_CONFIRM:
result = getUssdACK(portid,ussd_data);
switch(result)
{
case 0:
break;
case -1:
return SERVICE_EXIT_PPS;
break;
default:
if(result != 1)
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
return SERVICE_EXIT_PPS;
else
SendReinputTransferConfrimRequest(portid,USSD_TRANSFER);
}
result = ussd_data[0] - '0';
switch(result)
{
case CONFIRM_OK:
changeTransferState(portid,S_TRANSFER_PROCESSING);
break;
case CONFIRM_ENTER_AGAIN:
changeTransferState(portid,S_TRANSFER_IDLE);
break;
case CONFIRM_CANCEL:
changeTransferState(portid,S_TRANSFER_EXIT);
break;
default:
return SERVICE_EXIT_PPS;
break;
}
break;
}
break;
case S_TRANSFER_PROCESSING:
FeeTransferTransaction(shmp);
changeTransferState(portid,S_TRANSFER_EXIT);
break;
case S_USSD_FT_ALL_IN_ONE_INPUT:
strcpy((char *)shmp->process_info.ppsService.feeTransfer.account.number, shmp->process_info.tmpDigits);
result = WaitingForInputTransferOutAccount(shmp);
if(result != INPUT_SUCCESS)
{
SendTransferDstNumberErrorRequest(portid,USSD_TRANSFER);
changeTransferState(portid,S_TRANSFER_EXIT);
break;
}
if(checkTransferDestNumber(portid) == FALSE)
{
SendTransferDstNumberErrorRequest(portid,USSD_TRANSFER);
return SERVICE_EXIT_PPS;
}
result = checkTransferedPartialFee(&shmp->caller_info,shmp->process_info.ppsService.feeTransfer.fee);
switch(result)
{
case CHECK_TRANSFERED_FEE_INSUFFIENT:
SendTransferInsufficientFeeRequest(portid,USSD_TRANSFER);
break;
case CHECK_TRANSFERED_FEE_EXPIERED:
SendTransferExpiredAccountRequest(portid,USSD_TRANSFER);
break;
case CHECK_TRANSFERED_FEE_OK:
FeeTransferTransaction(shmp);
default:
break;
}
changeTransferState(portid,S_TRANSFER_EXIT);
break;
case S_USSD_FT_REST_START:
result = pps_rest_transfer_process(portid);
if(result != 0)
{
changeTransferState(portid,S_TRANSFER_EXIT);
}
break;
case S_TRANSFER_EXIT:
clearTransferInfo(portid);
return SERVICE_EXIT_PPS;
break;
}
return SERVICE_KEEP_STATE;
}
int chargeOrTransfer(u_short portid)
{
_state_data *shmp;
int result = SERVICE_KEEP_STATE,rst;
TRANSFER_FEE *feeTransfer;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER)
{
return SERVICE_EXIT_PPS;
}
switch(getTransferState(portid))
{
case S_TRANSFER_IDLE:
clearTransferInfo(portid);
changeTransferState(portid,S_WAIT_TRANSFER_CONFIRM);
playPromptAndCollectVoice(portid,CHARGE_OR_TRANSFER,1);
break;
case S_WAIT_TRANSFER_CONFIRM:
rst = WaitForChoice_chargeOrTransfer(shmp);
switch(rst)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
rst = getInputtedChoice(shmp);
switch(rst)
{
case CONFIRM_OK:
changeTransferState(portid,S_TRANSFER_EXIT);
break;
case CONFIRM_ENTER_AGAIN:
changeTransferState(portid,S_TRANSFER_EXIT);
break;
default:
result = SERVICE_EXIT_PPS;
break;
}
break;
case INPUT_ERROR_REINPUT:
playPromptAndCollectVoice(portid,CHARGE_OR_TRANSFER,1);
break;
case INPUT_ERROR_EXIT:
result = SERVICE_EXIT_PPS;
break;
}
break;
case S_TRANSFER_EXIT:
result = SERVICE_RETURN_TO_PARENT;
break;
default:
result = SERVICE_EXIT_PPS;
break;
}
return result;
}
int transferAccountIVRProc(u_short portid)
{
_state_data *shmp;
int result = SERVICE_KEEP_STATE,rst;
TRANSFER_FEE *feeTransfer;
PutLogFunID("transferPPSAccountProc");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER)
{
clearTransferInfo(portid);
return SERVICE_EXIT_PPS;
}
switch(getTransferState(portid))
{
case S_TRANSFER_IDLE:
if(isTransferAllowed(portid) == FALSE)
{
playPromptVoice(portid,SERIVCE_NOT_APPLIED);
changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR);
break;
}
rst = checkTransferedPartialFee(&shmp->caller_info,1.0);
if(rst == CHECK_TRANSFERED_FEE_INSUFFIENT)
{
playPromptVoice(portid,TRANSFERED_FEE_INSUFFIENT);
changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR);
return result;
}
clearTransferInfo(portid);
changeTransferState(portid,S_INPUT_DESTNUMBER);
break;
case S_INPUT_DESTNUMBER:
playPromptAndCollectVoice(portid,PleaseInputTransferInAccount,MAX_IVR_INPUT_LEN);
changeTransferState(portid,S_WART_INPUT_DESTNUMBER);
break;
case S_WART_INPUT_DESTNUMBER:
rst = WaitingForInputTransferOutAccount(shmp);
switch(rst)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
saveFirstInputtedTransferOutAccount(shmp);
changeTransferState(portid,S_INPUT_DESTNUMBER_AGAIN);
break;
case INPUT_ERROR_REINPUT:
playPromptAndCollectVoice(portid,InvalidAccountIputAgain,MAX_IVR_INPUT_LEN);
break;
case INPUT_ERROR_EXIT:
result = SERVICE_EXIT_PPS;
break;
}
break;
case S_INPUT_DESTNUMBER_AGAIN:
playPromptAndCollectVoice(portid,PleaseInputTransferInAccountAgain,MAX_IVR_INPUT_LEN);
changeTransferState(portid,S_WART_INPUT_DESTNUMBER_AGAIN);
break;
case S_WART_INPUT_DESTNUMBER_AGAIN:
rst = WaitingForInputTransferOutAccount(shmp);
switch(rst)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
changeTransferState(portid,S_MATCH_DESTNUMBER);
break;
case INPUT_ERROR_REINPUT:
playPromptAndCollectVoice(portid,InvalidAccountIputAgain,MAX_IVR_INPUT_LEN);
changeTransferState(portid,S_WART_INPUT_DESTNUMBER);
break;
case INPUT_ERROR_EXIT:
result = SERVICE_EXIT_PPS;
break;
}
break;
case S_MATCH_DESTNUMBER:
if(matchTwoInpuutedTransferOutAccount(shmp))
changeTransferState(portid,S_FULL_PARTIAL_TRANSFER_CHOICE);
else
changeTransferState(portid,S_DESTNUMBER_NOT_MATCHED);
break;
case S_DESTNUMBER_NOT_MATCHED:
playPromptVoice(portid,NotMatchedTransferOutAccount);
changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR);
break;
case S_FULL_PARTIAL_TRANSFER_CHOICE:
playPromptAndCollectVoice(portid,FULL_PARTIAL_TRANSFER_CHOICE,1);
changeTransferState(portid,S_WAIT_FULL_PARTIAL_TRANSFER_CHOICE);
break;
case S_WAIT_FULL_PARTIAL_TRANSFER_CHOICE:
rst = WaitForTransferMode(shmp);
switch(rst)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
rst = getInputtedChoice(shmp);
if( rst == FULL_TRANSFER_MODE)
{
rst = checkTransferedFullFee(shmp);
switch(rst)
{
case CHECK_TRANSFERED_FEE_OK:
changeTransferState(portid,S_TRANSFER_CONFIRM);
break;
case CHECK_TRANSFERED_FEE_INSUFFIENT:
playPromptVoice(portid,TRANSFERED_FEE_INSUFFIENT);
changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR);
break;
case CHECK_TRANSFERED_FEE_EXPIERED:
default:
playPromptVoice(portid,TRANSFERED_FEE_EXPIERED);
changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR);
break;
}
}
else if( rst == PARTIAL_TRANSFER_MODE)
changeTransferState(portid,S_INPUT_FEE_TRANSFERED);
else
changeTransferState(portid,S_FULL_PARTIAL_TRANSFER_CHOICE);
break;
case INPUT_ERROR_REINPUT:
playPromptAndCollectVoice(portid,FULL_PARTIAL_TRANSFER_CHOICE,1);
break;
case INPUT_ERROR_EXIT:
result = SERVICE_EXIT_PPS;
break;
}
break;
case S_INPUT_FEE_TRANSFERED:
playPromptAndCollectVoice(portid,INPUT_FEE_TRANSFERED,MAX_FEE_LENGTH);
changeTransferState(portid,S_WAIT_INPUT_FEE_TRANSFERED);
break;
case S_WAIT_INPUT_FEE_TRANSFERED:
rst = WaitingForInputTransferOutFee(shmp);
switch(rst)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
rst = checkTransferedPartialFee(&shmp->caller_info,shmp->process_info.ppsService.feeTransfer.fee);
switch(rst)
{
case CHECK_TRANSFERED_FEE_OK:
changeTransferState(portid,S_TRANSFER_CONFIRM);
break;
case CHECK_TRANSFERED_FEE_INSUFFIENT:
playPromptVoice(portid,TRANSFERED_FEE_INSUFFIENT);
changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR);
break;
case CHECK_TRANSFERED_FEE_EXPIERED:
default:
playPromptVoice(portid,TRANSFERED_FEE_EXPIERED);
changeTransferState(portid,S_PLAY_TRANSFERED_FEE_ERROR);
break;
}
break;
case INPUT_ERROR_REINPUT:
playPromptAndCollectVoice(portid,INPUT_FEE_TRANSFERED_FORMAT_ERROR,MAX_IVR_INPUT_LEN);
break;
case INPUT_ERROR_EXIT:
result = SERVICE_EXIT_PPS;
break;
}
break;
case S_TRANSFER_CONFIRM:
SendTransferInfoPromptToSrf(portid);
changeTransferState(portid,S_PLAY_TRANSFER_CONFIRM_SUCCESS);
break;
case S_PLAY_TRANSFER_CONFIRM_SUCCESS:
rst = CallingCardWaitingForSpecialResourceReport(shmp);
if(rst == SERVICE_KEEP_STATE)
break;
else if(rst == 1)
{
playPromptAndCollectVoice(portid,CONFIRM_LISTEN_AGAIN,1);
changeTransferState(portid,S_WAIT_TRANSFER_CONFIRM);
}
else
result = SERVICE_EXIT_PPS;
break;
case S_WAIT_TRANSFER_CONFIRM:
rst = WaitForChoice(shmp);
switch(rst)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
rst = getInputtedChoice(shmp);
switch(rst)
{
case CONFIRM_OK:
changeTransferState(portid,S_TRANSFER_PROCESSING);
break;
case CONFIRM_ENTER_AGAIN:
changeTransferState(portid,S_FULL_PARTIAL_TRANSFER_CHOICE);
break;
case CONFIRM_LISTEN_RE:
changeTransferState(portid,S_TRANSFER_CONFIRM);
break;
case CONFIRM_CANCEL:
default:
changeTransferState(portid,S_TRANSFER_EXIT);
break;
}
break;
case INPUT_ERROR_REINPUT:
playPromptAndCollectVoice(portid,CONFIRM_LISTEN_AGAIN,1);
break;
case INPUT_ERROR_EXIT:
result = SERVICE_EXIT_PPS;
break;
}
break;
case S_TRANSFER_PROCESSING:
FeeTransferTransaction(shmp);
playPromptVoice(portid,TransferSuccess);
changeTransferState(portid,S_PLAY_TRANSFERED_FEE_SUCCESS);
break;
case S_PLAY_TRANSFERED_FEE_SUCCESS:
rst = CallingCardWaitingForSpecialResourceReport(shmp);
if(rst == SERVICE_KEEP_STATE)
break;
else if(rst == 1)
{
changeTransferState(portid,S_TRANSFER_EXIT);
}
else
result = SERVICE_EXIT_PPS;
break;
case S_PLAY_TRANSFERED_FEE_ERROR:
rst = CallingCardWaitingForSpecialResourceReport(shmp);
if(rst == SERVICE_KEEP_STATE)
break;
else if(rst == 1)
{
changeTransferState(portid,S_TRANSFER_EXIT);
}
else
result = SERVICE_EXIT_PPS;
break;
case S_TRANSFER_EXIT:
clearTransferInfo(portid);
result = SERVICE_RETURN_TO_PARENT;
break;
default:
clearTransferInfo(portid);
result = SERVICE_EXIT_PPS;
break;
}
return result;
}