Files
ocs/mss/pps/src/main/masterSlaveCard.c
T
2025-03-08 16:40:56 +08:00

3085 lines
88 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"
extern PPSParamStruct ppsParam;
extern struct timeval tvnow;
extern _ram_data *ramshm_ptr;
extern _state_machine *smshm_ptr;;
extern u_short debug_messages;
extern int logMsgFlag;
extern int checkTransferedPartialFee(_account_info *callerInfo,float feeTransfered);
extern int StuffCapMessage(CapArg capArg, PCAP_Message pcap_message);
extern int ppsDebugCapMsg(CAP_Message *cap_message,int flag);
extern void FeeTransferTransaction(_state_data *shmp);
static int getParentNumber(_prepaid_info *prepaidInfo,u8 *parentNumber);
static int getMaxCalls(_prepaid_info *prepaidInfo);
static int getMaxSMS(_prepaid_info *prepaidInfo);
static int getMaxConsume(_prepaid_info *prepaidInfo);
static int getCallsMadeToday(_prepaid_info *prepaidInfo);
static int getSMSToday(_prepaid_info *prepaidInfo);
static int getConsumeFee(_prepaid_info *prepaidInfo);
static int checkMasterFee(u_short portid);
static int RealTransferToSlave(_state_data *shmp);
static int smppNotifyMasterADD(u_char *masterNumber,u_char *slaveNumber);
static int smppNotifyMasterDEL(u_char *masterNumber,u_char *slaveNumber);
static int smppNotifySlaveADD(u_char *masterNumber,u_char *slaveNumber);
static int smppNotifySlaveDEL(u_char *masterNumber,u_char *slaveNumber);
static int getAddSlaveCharge(_account_info *accountInfo);
static int getAddingSlaveCosId(_state_data *shmp,MASTER_SLAVE_ADD *add);
static u_char getChildNum(u_short portid);
static void setChildNum(u_short portid,u_char childNum);
extern BOOL isPromotionCanBeTransfered(_account_info *accountInfo);
int masterChangeSlaveCharge(_state_data *shmp,_account_info *slaveInfo);
int IncreasePoolAccountChangeCounter(int head, int tail);
void ppsgetdaytime_readFormat(char *daytime_buf);
enum{
S_MASTER_ADD_IDLE,
S_MASTER_ADD_WAIT_SLAVE,
S_MASTER_ADD_WAIT_COS,
S_MASTER_ADD_PLAY_CONFIRM,
S_MASTER_ADD_WAIT_PLAY_CONFIRM,
S_MASTER_ADD_WAIT_CONFIRM,
S_MASTER_ADD_PROCESSING,
S_MASTER_ADD_WAIT_PLAY_DONE,
S_MASTER_ADD_EXIT,
};
/****************************** enquiry ***********************************************/
/*inline */_prepaid_info *getPrepaidInfo(_account_info *account)
{
int head,tail;
if(account == NULL)
return NULL;
head = account->head;
tail = account->tail;
if (account->head < MSISDN_HEAD_NUM && account->tail < UNIT_STORE_ACCOUNT)
{
return &ramshm_ptr->prepaid_data.prepaid_info[head][tail];
//return 1;
}
return NULL;
}
int getHowManyChildren(_prepaid_info *prepaidInfo)
{
if(prepaidInfo == NULL)
return -1;
return prepaidInfo->poolAccount.roleParty.parent.childNumber;
}
int increMasterChildren(_prepaid_info *prepaidInfo)
{
if(prepaidInfo == NULL)
return 0;
prepaidInfo->poolAccount.roleParty.parent.childNumber++;
if(prepaidInfo->poolAccount.roleParty.parent.childNumber > POOL_MAX_CHILD)
prepaidInfo->poolAccount.roleParty.parent.childNumber = POOL_MAX_CHILD;
return prepaidInfo->poolAccount.roleParty.parent.childNumber;
}
int decMasterChildren(_prepaid_info *prepaidInfo)
{
if(prepaidInfo == NULL)
return 0;
if(prepaidInfo->poolAccount.roleParty.parent.childNumber <= 0)
prepaidInfo->poolAccount.roleParty.parent.childNumber = 0;
else
prepaidInfo->poolAccount.roleParty.parent.childNumber--;
return prepaidInfo->poolAccount.roleParty.parent.childNumber;
}
static int getChildNumber(_prepaid_info *prepaidInfo,u8 childIndex,u_char *childNumber)
{
u8 *bcdNumber,len;
if(prepaidInfo == NULL)
return -1;
if(childIndex <= 0 || childIndex > POOL_MAX_CHILD)
return -1;
bcdNumber = prepaidInfo->poolAccount.roleParty.parent.childMsisdn[childIndex - 1];
len = bcdNumber[MAX_MSISDN_BLEN-1];
/*
if(len > MAX_MSISDN_ALEN || len < 3)
return -1;
*/
BcdToAscii((char *)childNumber,bcdNumber,(MAX_MSISDN_BLEN-1)*2);
childNumber[len] = 0;
return len;
}
static void SendDesignatedVoiceAndCollectInfo(u_short portid)
{
int dlgid,invokeid=0,len;
u_char u_msisdn[12];
char buf[32];
CAP_Message cap_message;
CapArg capArg;
CapPromptAndCollectUserInformation *pPCUI;
CapMessageID *pMID;
_state_data *shmp=(_state_data *) &smshm_ptr->state_data;
PutLogFunID("SendFavPromptAndCollectUserInfo");
shmp += portid;
AddPPSStatistics(MIBPPS_PCUI,shmp->process_info.dir);
dlgid = shmp->context_info.dialogue_id;
capArg.ocode = CAP_OC_PromptAndCollectUserInformation;
capArg.message_flag = REQUEST;
capArg.port_id = portid;
capArg.dialogue_id = dlgid;
capArg.invoke_id = invokeid;
capArg.version = shmp->context_info.acn_ver;
pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg;
pPCUI->collectedInfo.choice_id = 0x00;
pPCUI->collectedInfo.collectedDigits.minimumNbOfDigits = 1;
pPCUI->collectedInfo.collectedDigits.maximumNbOfDigits =
shmp->process_info.maxPCUInfoLen;
pPCUI->collectedInfo.collectedDigits.optional_flag = 0x79;
memcpy(pPCUI->collectedInfo.collectedDigits.endOfReplyDigit,
shmp->process_info.endOfReplyDigit,3);
pPCUI->collectedInfo.collectedDigits.firstDigitTimeOut = 10;
pPCUI->collectedInfo.collectedDigits.interDigitTimeOut = 10;
pPCUI->collectedInfo.collectedDigits.errorTreatment = repeatPrompt;
pPCUI->collectedInfo.collectedDigits.interruptableAnnInd = 1;
pPCUI->optional_flag = 0x03;
pPCUI->disconnectFromIPForbidden = 0x01;
pPCUI->informationToSend.choice_id = 0x00;
pPCUI->informationToSend.inbandInfo.messageID.choice_id = 0x03;
pMID = &pPCUI->informationToSend.inbandInfo.messageID;
pMID->variableMessage.elementaryMessageID =
GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 +
+shmp->process_info.voiceID;
pMID->variableMessage.variableParts.num = 2;
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);
pMID->variableMessage.variableParts.variablePart[1].choice_id = 0;
pMID->variableMessage.variableParts.variablePart[1].integer = getChildNum(portid);
pPCUI->informationToSend.inbandInfo.optional_flag = 0x07;
pPCUI->informationToSend.inbandInfo.numberOfRepetitions = 0x01;
pPCUI->informationToSend.inbandInfo.duration = 0x00;
pPCUI->informationToSend.inbandInfo.interval = 0x01;
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
}
static void SendSlaveParentNumber(u_short portid)
{
u8 parentNumber[MAX_MSISDN_BLEN]={0},parentNumberAscci[MAX_MSISDN_BLEN*2]={0},u_msisdn[32]={0};
_prepaid_info *prepaidInfo;
int len;
_state_data *shmp;
int dlgid,invokeid=0;
CAP_Message cap_message;
CapArg capArg;
CapPlayAnnouncement *pPlayAnnouncement;
CapMessageID *pMID;
CapVariablePart *pV;
u8 index=0;
PutLogFunID("SendSlaveParentNumber");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir);
if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL)
return;
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;
pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID;
pMID->variableMessage.elementaryMessageID =
GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + SLAVE_ENQUIRY_PARENT_NUMBER;
pMID->variableMessage.variableParts.num = 1;
getParentNumber(prepaidInfo,parentNumber);
/********************************* parent number ************************************/
index = 0;
len = parentNumber[MAX_MSISDN_BLEN-1];
BcdToAscii((char *)parentNumberAscci,parentNumber,18);
StringCut((char *)parentNumberAscci,'F');
parentNumberAscci[len] = 0;
ppsAsciiToBcdR(u_msisdn, (char *)parentNumberAscci,len);
if(len>(MAX_MSISDN_BLEN-1)*2)
len = (MAX_MSISDN_BLEN - 1 )*2;
pV = &pMID->variableMessage.variableParts.variablePart[index];
pV->choice_id = 1;
pV->number[0] = (len+1)/2+1;
if(len%2==0)
{
pV->number[1] = 0x04;
memcpy(&pV->number[2],u_msisdn,(len+1)/2);
}
else
{
pV->number[1] = 0x24;
memcpy(&pV->number[2],u_msisdn,(len+1)/2);
pV->number[2+(len+1)/2] &=0x0F;
}
/********************************* parent number ************************************/
pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07;
pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01;
pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00;
pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01;
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;
}
static void SendSlaveLimits(u_short portid)
{
int maxConsumePerDay,maxCallsPerDay,maxSMSPerDay,balance,centbalance,hth_b,th_b,h_b,b_b;;
u8 buf[256]={0};
_prepaid_info *prepaidInfo;
int resolution=100;
//int len;
_state_data *shmp;
int dlgid,invokeid=0;
CAP_Message cap_message;
CapArg capArg;
CapPlayAnnouncement *pPlayAnnouncement;
CapMessageID *pMID;
CapVariablePart *pV;
u8 index=0;
PutLogFunID("SendSlaveLimits");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir);
if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL)
return;
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;
pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID;
pMID->variableMessage.elementaryMessageID =
GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + SLAVE_ENQUIRY_LIMITS;
pMID->variableMessage.variableParts.num = 3;
maxCallsPerDay = getMaxCalls(prepaidInfo);
maxSMSPerDay = getMaxSMS(prepaidInfo);
maxConsumePerDay = getMaxConsume(prepaidInfo);
resolution = getSystemCurrencyResolution();
/********************************* max calls per day ************************************/
index = 0;
pV = &pMID->variableMessage.variableParts.variablePart[index];
pV->choice_id = 0;
pV->integer = maxCallsPerDay;
/********************************* max calls per day ************************************/
/********************************* max SMS per day ************************************/
index = 1;
pV = &pMID->variableMessage.variableParts.variablePart[index];
pV->choice_id = 0;
pV->integer = maxSMSPerDay;
/********************************* max SMS per day ************************************/
/********************************* max consumption per day ************************************/
index = 2;
balance = maxConsumePerDay;
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);
pV = &pMID->variableMessage.variableParts.variablePart[index];
pV->choice_id = 4;
sprintf((char *)buf,"%02d",hth_b);
ppsAsciiToBcdR(&pV->price[0], (char *)buf,2);
sprintf((char *)buf,"%d%d",th_b,h_b);
ppsAsciiToBcdR(&pV->price[1], (char *)buf,2);
sprintf((char *)buf,"%02d",b_b);
ppsAsciiToBcdR(&pV->price[2], (char *)buf,2);
sprintf((char *)buf,"%02d",centbalance);
ppsAsciiToBcdR(&pV->price[3], (char *)buf,2);
/********************************* max consumption per day ************************************/
pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07;
pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01;
pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00;
pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01;
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;
}
static void SendSlaveToday(u_short portid)
{
int chargedToday,balance,centbalance,hth_b,th_b,h_b,b_b;
int dailedToday,smsToday;
u8 buf[256]={0};
_prepaid_info *prepaidInfo;
int resolution=100;
//int len;
_state_data *shmp;
int dlgid,invokeid=0;
CAP_Message cap_message;
CapArg capArg;
CapPlayAnnouncement *pPlayAnnouncement;
CapMessageID *pMID;
CapVariablePart *pV;
u8 index=0;
PutLogFunID("SendSlaveEnquiryResult");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir);
if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL)
return;
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;
/* account balance */
pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID;
pMID->variableMessage.elementaryMessageID =
GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + SLAVE_ENQUIRY_TODAY;
pMID->variableMessage.variableParts.num = 3;
dailedToday = getCallsMadeToday(prepaidInfo);
smsToday = getSMSToday(prepaidInfo);
chargedToday = getConsumeFee(prepaidInfo);
resolution = getSystemCurrencyResolution();
/********************************* calls today ************************************/
index = 0;
pV = &pMID->variableMessage.variableParts.variablePart[index];
pV->choice_id = 0;
pV->integer = dailedToday;
/********************************* calls today ************************************/
/********************************* SMS today ************************************/
index = 1;
pV = &pMID->variableMessage.variableParts.variablePart[index];
pV->choice_id = 0;
pV->integer = smsToday;
/********************************* SMS today ************************************/
/********************************* consumption today ************************************/
index = 2;
balance = chargedToday;
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);
pV = &pMID->variableMessage.variableParts.variablePart[index];
pV->choice_id = 4;
sprintf((char *)buf,"%02d",hth_b);
ppsAsciiToBcdR(&pV->price[0], (char *)buf,2);
sprintf((char *)buf,"%d%d",th_b,h_b);
ppsAsciiToBcdR(&pV->price[1], (char *)buf,2);
sprintf((char *)buf,"%02d",b_b);
ppsAsciiToBcdR(&pV->price[2], (char *)buf,2);
sprintf((char *)buf,"%02d",centbalance);
ppsAsciiToBcdR(&pV->price[3], (char *)buf,2);
/********************************* consumption today ************************************/
pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07;
pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01;
pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00;
pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01;
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;
}
static void SendSlaveInfo(u_short portid)
{
int dlgid,invokeid=0;
//u_char u_msisdn[12];
//char buf[32];
CAP_Message cap_message;
CapArg capArg;
CapPromptAndCollectUserInformation *pPCUI;
CapMessageID *pMID;
_state_data *shmp=(_state_data *) &smshm_ptr->state_data;
PutLogFunID("SendFavPromptAndCollectUserInfo");
shmp += portid;
AddPPSStatistics(MIBPPS_PCUI,shmp->process_info.dir);
dlgid = shmp->context_info.dialogue_id;
capArg.ocode = CAP_OC_PromptAndCollectUserInformation;
capArg.message_flag = REQUEST;
capArg.port_id = portid;
capArg.dialogue_id = dlgid;
capArg.invoke_id = invokeid;
capArg.version = shmp->context_info.acn_ver;
pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg;
pPCUI->collectedInfo.choice_id = 0x00;
pPCUI->collectedInfo.collectedDigits.minimumNbOfDigits = 1;
pPCUI->collectedInfo.collectedDigits.maximumNbOfDigits = 1;
pPCUI->collectedInfo.collectedDigits.optional_flag = 0x78;
pPCUI->collectedInfo.collectedDigits.firstDigitTimeOut = 10;
pPCUI->collectedInfo.collectedDigits.interDigitTimeOut = 10;
pPCUI->collectedInfo.collectedDigits.errorTreatment = repeatPrompt;
pPCUI->collectedInfo.collectedDigits.interruptableAnnInd = 1;
pPCUI->optional_flag = 0x03;
pPCUI->disconnectFromIPForbidden = 0x01;
pPCUI->informationToSend.choice_id = 0x00;
pPCUI->informationToSend.inbandInfo.messageID.choice_id = 0x03;
pMID = &pPCUI->informationToSend.inbandInfo.messageID;
pMID->variableMessage.elementaryMessageID =
GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + MASTER_CARD_HOW_MANY_CHILDREN;
pMID->variableMessage.variableParts.num = 2;
pMID->variableMessage.variableParts.variablePart[0].choice_id = 0;
pMID->variableMessage.variableParts.variablePart[0].integer = getChildNum(portid);
pMID->variableMessage.variableParts.variablePart[1].choice_id = 0;
pMID->variableMessage.variableParts.variablePart[1].integer = getChildNum(portid);
pPCUI->informationToSend.inbandInfo.optional_flag = 0x07;
pPCUI->informationToSend.inbandInfo.numberOfRepetitions = 0x01;
pPCUI->informationToSend.inbandInfo.duration = 0x00;
pPCUI->informationToSend.inbandInfo.interval = 0x01;
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
}
static void playChildNumber(u_short portid,u_char *childNumber)
{
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
shmp->process_info.voiceID = MASTER_CARD_CHILD_NUMBER;
strcpy(shmp->process_info.tmpDigits, (char *)childNumber);
SendDesignatedVoiceAndCollectInfo(portid);
}
#define changeEnquirySlaveState(portid,val) do { \
enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry;\
enquiry->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)
static inline u8 getEnquirySlaveState(portid)
{
_state_data *shmp;
MASTER_SLAVE_ENQUIRY *enquiry;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry;
return enquiry->state;
}
static int WaitForEnquirySalveSelect(_state_data *shmp)
{
u_char input_msg[64] = {0};
int result;
MASTER_SLAVE_ENQUIRY *enquiry;
memset(input_msg,0,64);
result = WaitingForInput(shmp,input_msg);
if(result != INPUT_SUCCESS)
return result;
enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry;
if(strlen((char *)input_msg) != 1
|| (input_msg[0] < '0' || input_msg[0] > enquiry->childNum +'0'))
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
else
return (result = INPUT_ERROR_REINPUT);
}
enquiry->choice = input_msg[0] - '0';
return result;
}
static int WaitForSlaveEnquiryFunc(_state_data *shmp)
{
u_char input_msg[64] = {0};
int result;
MASTER_SLAVE_ENQUIRY *enquiry;
PutLogFunID("WaitForChoice");
memset(input_msg,0,64);
result = WaitingForInput(shmp,input_msg);
if(result != INPUT_SUCCESS)
return result;
if(strlen((char *)input_msg) != 1
|| (input_msg[0] < '0' || input_msg[0] > '3'))
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
else
return (result = INPUT_ERROR_REINPUT);
}
enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry;
enquiry->choice = input_msg[0] - '0';
return result;
}
static int WaitForMasterEnquiryFunc(_state_data *shmp)
{
u_char input_msg[64] = {0};
int result;
MASTER_SLAVE_ENQUIRY *enquiry;
PutLogFunID("WaitForChoice");
memset(input_msg,0,64);
result = WaitingForInput(shmp,input_msg);
if(result != INPUT_SUCCESS)
return result;
if(strlen((char *)input_msg) != 1
|| (input_msg[0] < '0' || input_msg[0] > '3'))
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
else
return (result = INPUT_ERROR_REINPUT);
}
enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry;
enquiry->choice = input_msg[0] - '0';
return result;
}
static int getEnquiryChoice(_state_data *shmp)
{
MASTER_SLAVE_ENQUIRY *enquiry;
enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry;
return enquiry->choice;
}
static void clearEnquirySlaveInfo(u_short portid)
{
_state_data *shmp;
MASTER_SLAVE_ENQUIRY *enquiry;
PutLogFunID("clearEnquirySlaveInfo");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry;
memset(enquiry,0,sizeof(MASTER_SLAVE_ENQUIRY));
}
static void setChildNum(u_short portid,u_char childNum)
{
_state_data *shmp;
MASTER_SLAVE_ENQUIRY *enquiry;
PutLogFunID("clearEnquirySlaveInfo");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry;
enquiry->childNum = childNum;
}
static u_char getChildNum(u_short portid)
{
_state_data *shmp;
MASTER_SLAVE_ENQUIRY *enquiry;
PutLogFunID("clearEnquirySlaveInfo");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
enquiry = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.enquiry;
return enquiry->childNum;
}
static int getParentNumber(_prepaid_info *prepaidInfo,u8 *parentNumber)
{
u8 *bcdNumber;
if(prepaidInfo == NULL)
return -1;
bcdNumber = prepaidInfo->poolAccount.roleParty.child.parentMsisdn;
memcpy(parentNumber,bcdNumber,MAX_MSISDN_BLEN);
return 1;
}
static int getMaxCalls(_prepaid_info *prepaidInfo)
{
COSTable *cosTableItem;
u8 cos_id;
COS_Pool_Account *pA;
cos_id = prepaidInfo->cos_id%MaxCosTableItem;
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
pA = &cosTableItem->poolAccount[0];
return pA->roleParty.child.maxCallsPerDay;
}
static int getMaxSMS(_prepaid_info *prepaidInfo)
{
COSTable *cosTableItem;
u8 cos_id;
COS_Pool_Account *pA;
cos_id = prepaidInfo->cos_id%MaxCosTableItem;
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
pA = &cosTableItem->poolAccount[0];
return pA->roleParty.child.maxSMSPerDay;
}
static int getMaxConsume(_prepaid_info *prepaidInfo)
{
COSTable *cosTableItem;
u8 cos_id;
COS_Pool_Account *pA;
cos_id = prepaidInfo->cos_id%MaxCosTableItem;
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
pA = &cosTableItem->poolAccount[0];
return pA->roleParty.child.maxFeePerDay;
}
static int getCallsMadeToday(_prepaid_info *prepaidInfo)
{
return prepaidInfo->poolAccount.roleParty.child.callsToday;
}
static int getSMSToday(_prepaid_info *prepaidInfo)
{
return prepaidInfo->poolAccount.roleParty.child.smsToday;
}
static int getConsumeFee(_prepaid_info *prepaidInfo)
{
return abs(prepaidInfo->poolAccount.roleParty.child.chargedToday);
}
enum SLAVE_ENQUIRY_STATE
{
S_SLAVE_ENQUIRY_IDLE = 0,
S_SLAVE_ENQUIRY_PARENT,
S_SLAVE_ENQUIRY_LIMITS,
S_SLAVE_ENQUIRY_TODAY,
S_SLAVE_PLAY_INFO,
S_SLAVE_PLAY_DONE,
};
static int slaveEnquiryProc(u_short portid)
{
_state_data *shmp;
int result = SERVICE_KEEP_STATE,rst,choice;
//u_char childNumber[MAX_MSISDN_BLEN*2] = {0};
_prepaid_info *prepaidInfo;
MASTER_SLAVE_ENQUIRY *enquiry;
PutLogFunID("slaveEnquiryProc");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
switch(getEnquirySlaveState(portid))
{
case S_SLAVE_ENQUIRY_IDLE:
if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL)
return (result = SERVICE_EXIT_PPS);
clearEnquirySlaveInfo(portid);
playPromptAndCollectVoice(portid,SLAVE_ENQUIRY_MENU,1);
changeEnquirySlaveState(portid,S_SLAVE_PLAY_DONE);
break;
case S_SLAVE_ENQUIRY_PARENT:
SendSlaveParentNumber(portid);
changeEnquirySlaveState(portid,S_SLAVE_PLAY_INFO);
break;
case S_SLAVE_ENQUIRY_LIMITS:
SendSlaveLimits(portid);
changeEnquirySlaveState(portid,S_SLAVE_PLAY_INFO);
break;
case S_SLAVE_ENQUIRY_TODAY:
SendSlaveToday(portid);
changeEnquirySlaveState(portid,S_SLAVE_PLAY_INFO);
break;
case S_SLAVE_PLAY_INFO:
rst = CallingCardWaitingForSpecialResourceReport(shmp);
if(rst == SERVICE_KEEP_STATE)
break;
else if(rst == 1)
{
playPromptAndCollectVoice(portid,SLAVE_ENQUIRY_MENU,1);
changeEnquirySlaveState(portid,S_SLAVE_PLAY_DONE);
}
else
result = SERVICE_EXIT_PPS;
break;
case S_SLAVE_PLAY_DONE:
rst = WaitForSlaveEnquiryFunc(shmp);
switch(rst)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
choice = getEnquiryChoice(shmp);
switch(choice)
{
case 0:
result = SERVICE_RETURN_TO_PARENT;
break;
case 1:
changeEnquirySlaveState(portid,S_SLAVE_ENQUIRY_PARENT);
break;
case 2:
changeEnquirySlaveState(portid,S_SLAVE_ENQUIRY_LIMITS);
break;
case 3:
default:
changeEnquirySlaveState(portid,S_SLAVE_ENQUIRY_TODAY);
break;
}
break;
case INPUT_ERROR_REINPUT:
playPromptAndCollectVoice(portid,SLAVE_ENQUIRY_MENU,1);
break;
case INPUT_ERROR_EXIT:
result = SERVICE_EXIT_PPS;
break;
}
break;
}
return result;
}
enum MASTER_ENQUIRY_STATE
{
S_MASTER_ENQUIRY_IDLE = 0,
S_MASTER_ENQUIRY_SELECT_INDEX,
S_MASTER_ENQUIRY_SELECT_FUNC,
S_MASTER_ENQUIRY_WAIT_PLAY_DONE,
};
static int masterEnquiryProc(u_short portid)
{
_state_data *shmp;
int result = SERVICE_KEEP_STATE,rst,choice;
u_char childNumber[MAX_MSISDN_BLEN*2] = {0};
_prepaid_info *prepaidInfo;
MASTER_SLAVE_ENQUIRY *enquiry;
PutLogFunID("masterEnquiryProc");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
switch(getEnquirySlaveState(portid))
{
case S_MASTER_ENQUIRY_IDLE:
if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL)
return (result = SERVICE_EXIT_PPS);
clearEnquirySlaveInfo(portid);
rst = getHowManyChildren(prepaidInfo);
if(rst <= 0)
{
playPromptVoice(portid,ENQUIRY_EMPTY);
changeEnquirySlaveState(portid,S_MASTER_ENQUIRY_WAIT_PLAY_DONE);
}
else
{
setChildNum(portid,rst);
SendSlaveInfo(portid);
changeEnquirySlaveState(portid,S_MASTER_ENQUIRY_SELECT_INDEX);
}
break;
case S_MASTER_ENQUIRY_SELECT_INDEX:
rst = WaitForEnquirySalveSelect(shmp);
switch(rst)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL)
return (result = SERVICE_EXIT_PPS);
choice = getEnquiryChoice(shmp);
switch(choice)
{
case 0:
result = SERVICE_RETURN_TO_PARENT;
break;
default:
rst = getChildNumber(prepaidInfo,choice,childNumber);
if(rst > 0)
{
playChildNumber(portid,childNumber);
changeEnquirySlaveState(portid,S_MASTER_ENQUIRY_SELECT_INDEX);
}
else
{
playPromptAndCollectVoice(portid,NO_CHILD_NUMBER_RELATED,1);
changeEnquirySlaveState(portid,S_MASTER_ENQUIRY_SELECT_INDEX);
}
break;
}
break;
case INPUT_ERROR_REINPUT:
changeEnquirySlaveState(portid,S_MASTER_ENQUIRY_IDLE);
break;
case INPUT_ERROR_EXIT:
result = SERVICE_EXIT_PPS;
break;
}
break;
case S_MASTER_ENQUIRY_WAIT_PLAY_DONE:
rst = CallingCardWaitingForSpecialResourceReport(shmp);
if(rst == SERVICE_KEEP_STATE)
break;
else if(rst == 1)
{
result = SERVICE_RETURN_TO_PARENT;
}
else
result = SERVICE_EXIT_PPS;
break;
}
return result;
}
/****************************** enquiry ***********************************************/
/****************************** add ***********************************************/
#define changeMasterAddState(portid,val) do { \
add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add;\
add->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)
static inline u8 getMasterAddState(portid)
{
_state_data *shmp;
MASTER_SLAVE_ADD *add;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add;
return add->state;
}
static void clearMasterAddInfo(u_short portid)
{
_state_data *shmp;
MASTER_SLAVE_ADD *add;
PutLogFunID("clearAddSlaveInfo");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add;
memset(add,0,sizeof(MASTER_SLAVE_ADD));
}
static int isMasterFullSlave(u_short portid)
{
_prepaid_info *prepaidInfo;
u8 result;
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL)
return TRUE;
result = getHowManyChildren(prepaidInfo);
if(result >= POOL_MAX_CHILD)
return TRUE;
return FALSE;
}
static int WaitingForMasterAddInputSlave(_state_data *shmp)
{
u8 input_msg[64] = {0},len,i;
//float fee;
int result;
MASTER_SLAVE_ADD *add;
PutLogFunID("WaitingForMasterInputSlave");
memset(input_msg,0,64);
result = WaitingForInput(shmp,input_msg);
if(result != INPUT_SUCCESS)
return result;
len = strlen((char *)input_msg) % (2*MAX_MSISDN_BLEN);
if(len > MAX_MSISDN_ALEN || len < 3)
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
else
return (result = INPUT_ERROR_REINPUT);
}
for(i=0;i<len;i++)
{
if(input_msg[i] < '0' || input_msg[i] > '9')
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
else
return (result = INPUT_ERROR_REINPUT);
}
}
CutUnknownPrefix((char *)input_msg);
if(!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);
}
add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add;
strcpy((char *)add->slaveInfo.number, (char *)input_msg);
return result;
}
static int SendMasterAddConfirmToSrf(u_short portid)
{
u8 slaveNumber[MAX_MSISDN_BLEN];
int len;
_state_data *shmp;
int dlgid,invokeid=0;
CAP_Message cap_message;
CapArg capArg;
CapPlayAnnouncement *pPlayAnnouncement;
CapMessageID *pMID;
CapVariablePart *pV;
u8 index=0;
MASTER_SLAVE_ADD *add;
PutLogFunID("SendMasterAddConfirmToSrf");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
AddPPSStatistics(MIBPPS_PLAY_ANNOUNCEMENT,shmp->process_info.dir);
add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add;
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;
pMID = &pPlayAnnouncement->informationToSend.inbandInfo.messageID;
pMID->variableMessage.elementaryMessageID =
GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + MASTER_CONFIRM_ADD;
pMID->variableMessage.variableParts.num = 2;
/********************************* slave number ************************************/
index = 0;
len = strlen((char *)add->slaveInfo.number);
ppsAsciiToBcdR(slaveNumber, (char *)add->slaveInfo.number,len);
if(len>(MAX_MSISDN_BLEN-1)*2)
len = (MAX_MSISDN_BLEN - 1 )*2;
pV = &pMID->variableMessage.variableParts.variablePart[index];
pV->choice_id = 1;
pV->number[0] = (len+1)/2+1;
if(len%2==0)
{
pV->number[1] = 0x04;
memcpy(&pV->number[2],slaveNumber,(len+1)/2);
}
else
{
pV->number[1] = 0x24;
memcpy(&pV->number[2],slaveNumber,(len+1)/2);
pV->number[2+(len+1)/2] &=0x0F;
}
/********************************* slave number ************************************/
index = 1;
pV = &pMID->variableMessage.variableParts.variablePart[index];
pV->choice_id = 0;
pV->integer = add->cosID;
pPlayAnnouncement->informationToSend.inbandInfo.optional_flag = 0x07;
pPlayAnnouncement->informationToSend.inbandInfo.numberOfRepetitions = 0x01;
pPlayAnnouncement->informationToSend.inbandInfo.duration = 0x00;
pPlayAnnouncement->informationToSend.inbandInfo.interval = 0x01;
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;
}
static int checkAddSlaveNumber(_state_data *shmp)
{
//MASTER_SLAVE_ADD *add;
u_char slaveBCD[MAX_MSISDN_BLEN];
_account_info *slave_info;
_prepaid_info *prepaidInfo;
int i,len;
PutLogFunID("checkAddSlaveNumber");
slave_info = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add.slaveInfo;
if(GetAccountPos(slave_info) == FALSE)
{
return 2;
}
if((prepaidInfo = getPrepaidInfo(slave_info)) == NULL)
return 2;
if(prepaidInfo->poolAccount.role != MASTER_SLAVE_NONE)
return 1;
memset(slaveBCD,0,MAX_MSISDN_BLEN);
len = strlen((char *)slave_info->number);
AsciiToBcd(slaveBCD, (char *)slave_info->number,(len+1)/2*2);
slaveBCD[MAX_MSISDN_BLEN-1] = len;
if(len %2 ==0)
slaveBCD[len/2] = 0xFF;
else
slaveBCD[len/2] |= 0x0F;
for(i=0;i<POOL_MAX_CHILD;i++)
{
if(prepaidInfo->poolAccount.roleParty.parent.childMsisdn[i][MAX_MSISDN_BLEN-1] < 3)
continue;
if(!memcmp(slaveBCD,prepaidInfo->poolAccount.roleParty.parent.childMsisdn[i],(len+1)/2*2))
return 1;
}
return 0;
}
static int WaitingForMasterAddInputCos(_state_data *shmp)
{
u_char input_msg[64] = {0};
int result;
MASTER_SLAVE_ADD *add;
memset(input_msg,0,64);
result = WaitingForInput(shmp,input_msg);
if(result != INPUT_SUCCESS)
return result;
if(strlen((char *)input_msg) != 1
|| (input_msg[0] < '0' || input_msg[0] > '1'))
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
else
return (result = INPUT_ERROR_REINPUT);
}
add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add;
add->cosID = input_msg[0] - '0';
return result;
}
static int masterAddWaitForChoice(_state_data *shmp)
{
u_char input_msg[64] = {0};
int result;
MASTER_SLAVE_ADD *add;
memset(input_msg,0,64);
result = WaitingForInput(shmp,input_msg);
if(result != INPUT_SUCCESS)
return result;
if(strlen((char *)input_msg) != 1
|| (input_msg[0] < '0' || input_msg[0] > '3'))
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
else
return (result = INPUT_ERROR_REINPUT);
}
add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add;
add->choice= input_msg[0] - '0';
return result;
}
static int getMasterAddChoice(_state_data *shmp)
{
MASTER_SLAVE_ADD *add;
add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add;
return add->choice;
}
static void addProcessSetMaster(_state_data *shmp)
{
_account_info *slave_info;
_prepaid_info *prepaidInfo;
UserData_Pool_Account *poolAccount;
u8 len,index,*childMsisdnBCD;
u_char *childMsisdnASCCI;
int charge;
slave_info = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add.slaveInfo;
if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL)
return;
poolAccount = &prepaidInfo->poolAccount;
poolAccount->role = MASTER_SLAVE_PARENT;
for(index=0;index<POOL_MAX_CHILD;index++)
{
if(poolAccount->roleParty.parent.childMsisdn[index][MAX_MSISDN_BLEN-1] < 3)
break;
}
if(index >= POOL_MAX_CHILD)
return;
childMsisdnBCD = poolAccount->roleParty.parent.childMsisdn[index];
memset(childMsisdnBCD,0,MAX_MSISDN_BLEN);
childMsisdnASCCI = slave_info->number;
len = strlen((char *)childMsisdnASCCI);
AsciiToBcd(childMsisdnBCD, (char *)childMsisdnASCCI,(len+1)/2*2);
childMsisdnBCD[MAX_MSISDN_BLEN-1] = len;
if(len %2 ==0)
childMsisdnBCD[len/2] = 0xFF;
else
childMsisdnBCD[len/2] |= 0x0F;
increMasterChildren(prepaidInfo);
charge = masterChangeSlaveCharge(shmp,slave_info);
smppNotifyMasterADD(shmp->caller_info.number,slave_info->number);
SendAccountRealSync_2(&shmp->caller_info,-charge,0.0,OMC_OCODE_EDIT);
}
static void addProcessSetSlave(_state_data *shmp)
{
_account_info *slave_info;
_prepaid_info *prepaidInfo,*master;
UserData_Pool_Account *poolAccount;
COSTable *cosTableItem;
u8 len,tmp;
slave_info = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add.slaveInfo;
if((master = getPrepaidInfo(&shmp->caller_info)) == NULL)
return;
if((prepaidInfo = getPrepaidInfo(slave_info)) == NULL)
return ;
poolAccount = &prepaidInfo->poolAccount;
poolAccount->role = MASTER_SLAVE_CHILD;
memset(poolAccount->roleParty.child.parentMsisdn,0xff,MAX_MSISDN_BLEN);
len = strlen((char *)shmp->caller_info.number);
AsciiToBcd(poolAccount->roleParty.child.parentMsisdn, (char *)shmp->caller_info.number,(len+1)/2*2);
poolAccount->roleParty.child.parentMsisdn[MAX_MSISDN_BLEN-1] = len;
if(len %2 ==0)
poolAccount->roleParty.child.parentMsisdn[len/2] = 0xFF;
else
poolAccount->roleParty.child.parentMsisdn[len/2] |= 0x0F;
poolAccount->roleParty.child.callsToday = 0;
poolAccount->roleParty.child.chargedToday = 0;
cosTableItem = &ppsParam.ppsTables.cosTable[master->cos_id];
tmp = shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add.cosID%MAX_CHILD_COS_PER_PARENT;
prepaidInfo->cos_id = cosTableItem->poolAccount[0].roleParty.parent.cosIDForChild[tmp];
smppNotifySlaveADD(shmp->caller_info.number,slave_info->number);
SendAccountRealSync_2(slave_info,0.0,0.0,OMC_OCODE_EDIT);
}
static int masterAddProc(u_short portid)
{
_state_data *shmp;
int result = SERVICE_KEEP_STATE,rst;
MASTER_SLAVE_ADD *add;
PutLogFunID("addProc");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
switch(getMasterAddState(portid))
{
case S_MASTER_ADD_IDLE:
clearMasterAddInfo(portid);
if(isMasterFullSlave(portid) == TRUE)
{
playPromptVoice(portid,ADD_FAIL_FULL);
changeMasterAddState(portid,S_MASTER_ADD_WAIT_PLAY_DONE);
}
else
{
playPromptAndCollectVoice(portid,MASTER_INPUT_CHILD_ADD,MAX_IVR_INPUT_LEN);
changeMasterAddState(portid,S_MASTER_ADD_WAIT_SLAVE);
}
break;
case S_MASTER_ADD_WAIT_SLAVE:
rst = WaitingForMasterAddInputSlave(shmp);
switch(rst)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
rst = checkAddSlaveNumber(shmp);
switch(rst)
{
case 0:
playPromptAndCollectVoice(portid,MASTER_SELECT_COS,1);
changeMasterAddState(portid,S_MASTER_ADD_WAIT_COS);
break;
case 1:/* is already a master or slave number */
playPromptAndCollectVoice(portid,ADD_FAIL_ALREADY_EXIST,MAX_IVR_INPUT_LEN);
changeMasterAddState(portid,S_MASTER_ADD_IDLE);
break;
case 2:/* not exist in pps */
playPromptAndCollectVoice(portid,InvalidAccountIputAgain,MAX_IVR_INPUT_LEN);
break;
}
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_MASTER_ADD_WAIT_COS:
rst = WaitingForMasterAddInputCos(shmp);
switch(rst)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
rst = checkMasterFee(portid);
switch(rst)
{
case CHECK_TRANSFERED_FEE_OK:
changeMasterAddState(portid,S_MASTER_ADD_PLAY_CONFIRM);
break;
case CHECK_TRANSFERED_FEE_INSUFFIENT:
playPromptVoice(portid,TRANSFERED_FEE_INSUFFIENT);
changeMasterAddState(portid,S_MASTER_ADD_WAIT_PLAY_DONE);
break;
case CHECK_TRANSFERED_FEE_EXPIERED:
default:
playPromptVoice(portid,TRANSFERED_FEE_EXPIERED);
changeMasterAddState(portid,S_MASTER_ADD_WAIT_PLAY_DONE);
break;
}
break;
case INPUT_ERROR_REINPUT:
playPromptAndCollectVoice(portid,MASTER_SELECT_COS,1);
break;
case INPUT_ERROR_EXIT:
result = SERVICE_EXIT_PPS;
break;
}
break;
case S_MASTER_ADD_PLAY_CONFIRM:
SendMasterAddConfirmToSrf(portid);
changeMasterAddState(portid,S_MASTER_ADD_WAIT_PLAY_CONFIRM);
break;
case S_MASTER_ADD_WAIT_PLAY_CONFIRM:
rst = CallingCardWaitingForSpecialResourceReport(shmp);
if(rst == SERVICE_KEEP_STATE)
break;
else if(rst == 1)
{
playPromptAndCollectVoice(portid,CONFIRM_LISTEN_AGAIN,1);
changeMasterAddState(portid,S_MASTER_ADD_WAIT_CONFIRM);
}
else
result = SERVICE_EXIT_PPS;
break;
case S_MASTER_ADD_WAIT_CONFIRM:
rst = masterAddWaitForChoice(shmp);
switch(rst)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
rst = getMasterAddChoice(shmp);
switch(rst)
{
case CONFIRM_OK:
changeMasterAddState(portid,S_MASTER_ADD_PROCESSING);
break;
case CONFIRM_ENTER_AGAIN:
changeMasterAddState(portid,S_MASTER_ADD_IDLE);
break;
case CONFIRM_LISTEN_RE:
changeMasterAddState(portid,S_MASTER_ADD_PLAY_CONFIRM);
break;
case CONFIRM_CANCEL:
changeMasterAddState(portid,S_MASTER_ADD_EXIT);
break;
}
break;
case INPUT_ERROR_REINPUT:
playPromptAndCollectVoice(portid,YES_OR_NO,1);
break;
case INPUT_ERROR_EXIT:
result = SERVICE_EXIT_PPS;
break;
}
break;
case S_MASTER_ADD_PROCESSING:
addProcessSetMaster(shmp);
addProcessSetSlave(shmp);
RealTransferToSlave(shmp);
playPromptVoice(portid,MASTER_ADD_SUCCESS);
changeMasterAddState(portid,S_MASTER_ADD_WAIT_PLAY_DONE);
break;
case S_MASTER_ADD_WAIT_PLAY_DONE:
rst = CallingCardWaitingForSpecialResourceReport(shmp);
if(rst == SERVICE_KEEP_STATE)
break;
else if(rst == 1)
{
changeMasterAddState(portid,S_MASTER_ADD_EXIT);
}
else
result = SERVICE_EXIT_PPS;
break;
case S_MASTER_ADD_EXIT:
result = SERVICE_RETURN_TO_PARENT;
break;
default:
result = SERVICE_EXIT_PPS;
break;
}
return result;
}
/****************************** add ***********************************************/
/****************************** delete ***********************************************/
#define changeMasterDelState(portid,val) do { \
del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del;\
del->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)
static inline u8 getMasterDelState(portid)
{
_state_data *shmp;
MASTER_SLAVE_DEL *del;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del;
return del->state;
}
static void clearMasterDelInfo(u_short portid)
{
_state_data *shmp;
MASTER_SLAVE_DEL *del;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del;
memset(del,0,sizeof(MASTER_SLAVE_DEL));
}
static int isMasterEmptySlave(u_short portid)
{
_prepaid_info *prepaidInfo;
u8 result;
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL)
return TRUE;
result = getHowManyChildren(prepaidInfo);
if(result <= 0)
return TRUE;
return FALSE;
}
static int WaitingForMasterDelInputSlave(_state_data *shmp)
{
u8 input_msg[64] = {0},len,i;
int result;
MASTER_SLAVE_DEL *del;
memset(input_msg,0,64);
result = WaitingForInput(shmp,input_msg);
if(result != INPUT_SUCCESS)
return result;
len = strlen((char *)input_msg) % (2*MAX_MSISDN_BLEN);
for(i=0;i<len;i++)
{
if(input_msg[i] < '0' || input_msg[i] > '9')
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
else
return (result = INPUT_ERROR_REINPUT);
}
}
CutUnknownPrefix((char *)input_msg);
del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del;
strcpy((char *)del->slaveInfo.number, (char *)input_msg);
return result;
}
static void SendMasterDelConfirmToSrf(u_short portid)
{
int dlgid,invokeid=0,len;
u_char u_msisdn[12];
//char buf[32];
CAP_Message cap_message;
CapArg capArg;
CapPromptAndCollectUserInformation *pPCUI;
CapMessageID *pMID;
MASTER_SLAVE_DEL *del;
_state_data *shmp=(_state_data *) &smshm_ptr->state_data;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
PutLogFunID("SendFavPromptAndCollectUserInfo");
AddPPSStatistics(MIBPPS_PCUI,shmp->process_info.dir);
del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del;
dlgid = shmp->context_info.dialogue_id;
capArg.ocode = CAP_OC_PromptAndCollectUserInformation;
capArg.message_flag = REQUEST;
capArg.port_id = portid;
capArg.dialogue_id = dlgid;
capArg.invoke_id = invokeid;
capArg.version = shmp->context_info.acn_ver;
pPCUI = &capArg.msg_list.promptAndCollectUserInformationArg;
pPCUI->collectedInfo.choice_id = 0x00;
pPCUI->collectedInfo.collectedDigits.minimumNbOfDigits = 1;
pPCUI->collectedInfo.collectedDigits.maximumNbOfDigits = 1;
pPCUI->collectedInfo.collectedDigits.optional_flag = 0x78;
pPCUI->collectedInfo.collectedDigits.firstDigitTimeOut = 10;
pPCUI->collectedInfo.collectedDigits.interDigitTimeOut = 10;
pPCUI->collectedInfo.collectedDigits.errorTreatment = repeatPrompt;
pPCUI->collectedInfo.collectedDigits.interruptableAnnInd = 0;
pPCUI->optional_flag = 0x03;
pPCUI->disconnectFromIPForbidden = 0x01;
pPCUI->informationToSend.choice_id = 0x00;
pPCUI->informationToSend.inbandInfo.messageID.choice_id = 0x03;
pMID = &pPCUI->informationToSend.inbandInfo.messageID;
pMID->variableMessage.elementaryMessageID =
GetAccountVoiceID(shmp->caller_info.head,shmp->caller_info.tail)*65536 + MASTER_CONFIRM_DEL;
pMID->variableMessage.variableParts.num = 1;
pMID->variableMessage.variableParts.variablePart[0].choice_id = 1;
len = strlen((char *)del->slaveInfo.number);
ppsAsciiToBcdR(u_msisdn, (char *)del->slaveInfo.number,len);
if(len>(MAX_MSISDN_BLEN-1)*2)
len = (MAX_MSISDN_BLEN - 1 )*2;
pMID->variableMessage.variableParts.variablePart[0].number[0] = (len+1)/2+1;
if(len%2==0)
{
pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x04;
memcpy(&pMID->variableMessage.variableParts.variablePart[0].number[2],
u_msisdn,
(len+1)/2);
}
else
{
pMID->variableMessage.variableParts.variablePart[0].number[1] = 0x24;
memcpy(&pMID->variableMessage.variableParts.variablePart[0].number[2],
u_msisdn,
(len+1)/2);
pMID->variableMessage.variableParts.variablePart[0].number[2+(len+1)/2] &=0x0F;
}
pPCUI->informationToSend.inbandInfo.optional_flag = 0x07;
pPCUI->informationToSend.inbandInfo.numberOfRepetitions = 0x01;
pPCUI->informationToSend.inbandInfo.duration = 0x00;
pPCUI->informationToSend.inbandInfo.interval = 0x01;
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
}
static int checkDelSlaveNumber(_state_data *shmp)
{
u_char *slaveNumber,slaveStoredNumber[2*MAX_MSISDN_BLEN];
_account_info *slave_info;
_prepaid_info *prepaidInfo;
u8 len,i,totalChild,*pChild;
PutLogFunID("checkDelSlaveNumber");
slave_info = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del.slaveInfo;
slaveNumber = slave_info->number;
if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL)
return 1;
if(GetAccountPos(slave_info) == FALSE)
{
return 2;
}
totalChild = prepaidInfo->poolAccount.roleParty.parent.childNumber%(POOL_MAX_CHILD+1);
for(i=0;i<totalChild;i++)
{
pChild = prepaidInfo->poolAccount.roleParty.parent.childMsisdn[i];
len = pChild[MAX_MSISDN_BLEN-1];
BcdToAscii((char *)slaveStoredNumber,pChild,18);
StringCut((char *)slaveStoredNumber,'F');
slaveStoredNumber[len] = 0;
if(!strcmp((char *)slaveNumber, (char *)slaveStoredNumber))
return 0;
}
return 1;
}
static int masterDelWaitForChoice(_state_data *shmp)
{
u_char input_msg[64] = {0};
int result;
MASTER_SLAVE_DEL *del;
memset(input_msg,0,64);
result = WaitingForInput(shmp,input_msg);
if(result != INPUT_SUCCESS)
return result;
if(strlen((char *)input_msg) != 1
|| (input_msg[0] < '0' || input_msg[0] > '2'))
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
else
return (result = INPUT_ERROR_REINPUT);
}
del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del;
del->choice = input_msg[0] - '0';
return result;
}
static int getMasterDelChoice(_state_data *shmp)
{
MASTER_SLAVE_DEL *del;
del = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del;
return del->choice;
}
static void delProcessSetMaster(_state_data *shmp)
{
_account_info *slave_info;
_prepaid_info *prepaidInfo;
UserData_Pool_Account *poolAccount;
u8 len,i,totalChild,*pChild;
u_char *slaveNumber,slaveStoredNumber[2*MAX_MSISDN_BLEN];
slave_info = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del.slaveInfo;
slaveNumber = slave_info->number;
if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL)
return;
poolAccount = &prepaidInfo->poolAccount;
totalChild = poolAccount->roleParty.parent.childNumber%(POOL_MAX_CHILD+1);
if(totalChild == 0)
{
poolAccount->role = MASTER_SLAVE_NONE;
return;
}
for(i=0;i<totalChild;i++)
{
pChild = poolAccount->roleParty.parent.childMsisdn[i];
len = pChild[MAX_MSISDN_BLEN-1];
BcdToAscii((char *)slaveStoredNumber,pChild,18);
StringCut((char *)slaveStoredNumber,'F');
slaveStoredNumber[len] = 0;
if(!strcmp((char *)slaveNumber, (char *)slaveStoredNumber))
break;
}
if(i >= totalChild)
return;
if(i >= totalChild-1)
memset(&poolAccount->roleParty.parent.childMsisdn[i],0,MAX_MSISDN_BLEN);
else
{
memmove(&poolAccount->roleParty.parent.childMsisdn[i],
&poolAccount->roleParty.parent.childMsisdn[i+1],
(totalChild-i-1)*MAX_MSISDN_BLEN);
memset(&poolAccount->roleParty.parent.childMsisdn[totalChild-1],0,MAX_MSISDN_BLEN);
}
totalChild = decMasterChildren(prepaidInfo);
if(totalChild <= 0)
poolAccount->role = MASTER_SLAVE_NONE;
smppNotifyMasterDEL(shmp->caller_info.number,slave_info->number);
SendAccountRealSync_2(&shmp->caller_info,0.0,0.0,OMC_OCODE_EDIT);
}
static void delProcessSetSlave(_state_data *shmp)
{
_account_info *slave_info;
_prepaid_info *prepaidInfo;
UserData_Pool_Account *poolAccount;
slave_info = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.del.slaveInfo;
if((prepaidInfo = getPrepaidInfo(slave_info)) == NULL)
return ;
poolAccount = &prepaidInfo->poolAccount;
memset(poolAccount,0,sizeof(UserData_Pool_Account));
poolAccount->role = MASTER_SLAVE_NONE;
smppNotifySlaveDEL(shmp->caller_info.number,slave_info->number);
SendAccountRealSync_2(slave_info,0.0,0.0,OMC_OCODE_EDIT);
}
enum{
S_MASTER_DEL_IDLE,
S_MASTER_DEL_WAIT_SLAVE,
S_MASTER_DEL_WAIT_CONFIRM,
S_MASTER_DEL_PROCESSING,
S_MASTER_DEL_WAIT_PLAY_DONE,
S_MASTER_DEL_EXIT,
};
static int masterDelProc(u_short portid)
{
_state_data *shmp;
int result = SERVICE_KEEP_STATE,rst;
MASTER_SLAVE_DEL *del;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
switch(getMasterDelState(portid))
{
case S_MASTER_DEL_IDLE:
clearMasterDelInfo(portid);
if(isMasterEmptySlave(portid) == TRUE)
{
playPromptVoice(portid,DEL_FAIL_EMPTY);
changeMasterDelState(portid,S_MASTER_DEL_WAIT_PLAY_DONE);
}
else
{
playPromptAndCollectVoice(portid,MASTER_INPUT_CHILD_DEL,MAX_IVR_INPUT_LEN);
changeMasterDelState(portid,S_MASTER_DEL_WAIT_SLAVE);
}
break;
case S_MASTER_DEL_WAIT_SLAVE:
rst = WaitingForMasterDelInputSlave(shmp);
switch(rst)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
rst = checkDelSlaveNumber(shmp);
switch(rst)
{
case 0:
SendMasterDelConfirmToSrf(portid);
changeMasterDelState(portid,S_MASTER_DEL_WAIT_CONFIRM);
break;
case 1:/* not your child */
playPromptAndCollectVoice(portid,DEL_FAIL_NOT_YOUR_CHILD,MAX_IVR_INPUT_LEN);
break;
case 2:/* not exist in pps */
playPromptAndCollectVoice(portid,InvalidAccountIputAgain,MAX_IVR_INPUT_LEN);
break;
}
break;
case INPUT_ERROR_REINPUT:
playPromptAndCollectVoice(portid,MASTER_INPUT_CHILD_DEL,MAX_IVR_INPUT_LEN);
break;
case INPUT_ERROR_EXIT:
result = SERVICE_EXIT_PPS;
break;
}
break;
case S_MASTER_DEL_WAIT_CONFIRM:
rst = masterDelWaitForChoice(shmp);
switch(rst)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
rst = getMasterDelChoice(shmp);
switch(rst)
{
case CONFIRM_OK:
changeMasterDelState(portid,S_MASTER_DEL_PROCESSING);
break;
case CONFIRM_ENTER_AGAIN:
changeMasterDelState(portid,S_MASTER_DEL_IDLE);
break;
case CONFIRM_CANCEL:
changeMasterDelState(portid,S_MASTER_DEL_EXIT);
break;
}
break;
case INPUT_ERROR_REINPUT:
playPromptAndCollectVoice(portid,YES_OR_NO,1);
break;
case INPUT_ERROR_EXIT:
result = SERVICE_EXIT_PPS;
break;
}
break;
case S_MASTER_DEL_PROCESSING:
delProcessSetMaster(shmp);
delProcessSetSlave(shmp);
playPromptVoice(portid,MASTER_DEL_SUCCESS);
changeMasterDelState(portid,S_MASTER_DEL_WAIT_PLAY_DONE);
break;
case S_MASTER_DEL_WAIT_PLAY_DONE:
rst = CallingCardWaitingForSpecialResourceReport(shmp);
if(rst == SERVICE_KEEP_STATE)
break;
else if(rst == 1)
{
changeMasterDelState(portid,S_MASTER_DEL_EXIT);
}
else
result = SERVICE_EXIT_PPS;
break;
case S_MASTER_DEL_EXIT:
result = SERVICE_RETURN_TO_PARENT;
break;
default:
result = SERVICE_EXIT_PPS;
break;
}
return result;
}
/****************************** delete ***********************************************/
#define changeMasterSlaveState(portid,val) do { \
masterSlaveCard = &shmp->process_info.ppsService.masterSlaveCard;\
masterSlaveCard->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)
static inline u8 getMasterSlaveState(portid)
{
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
return shmp->process_info.ppsService.masterSlaveCard.state;
}
static int WaitForMasterChoice(_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(strlen((char *)input_msg) != 1
|| (input_msg[0] < '0' || input_msg[0] > '3'))
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
else
return (result = INPUT_ERROR_REINPUT);
}
shmp->process_info.ppsService.masterSlaveCard.choice = input_msg[0] - '0';
return result;
}
static int WaitForSalveChoice(_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(strlen((char *)input_msg) != 1
|| (input_msg[0] < '0' || input_msg[0] > '1'))
{
if(shmp->process_info.serviceInput++ >= SERVICE_INPUT_NUM)
{
return (result = INPUT_ERROR_EXIT);
}
else
return (result = INPUT_ERROR_REINPUT);
}
shmp->process_info.ppsService.masterSlaveCard.choice = input_msg[0] - '0';
return result;
}
static int getMasterSalveFunc(_state_data *shmp)
{
return shmp->process_info.ppsService.masterSlaveCard.choice;
}
enum MASTER_SLAVE_CARD_STATE{
S_MASTER_SLAVE_IDLE,
S_MASTER_CHOICE,
S_SLAVE_CHOICE,
S_MASTER_INQUIRY,
S_SLAVE_INQUIRY,
S_MASTER_ADD_SLAVE,
S_MASTER_DEL_SLAVE,
S_MASTER_PLAY,
};
void clearMasterSlaveInfo(u_short portid)
{
_state_data *shmp;
PutLogFunID("clearTransferInfo");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
memset(&shmp->process_info.ppsService.masterSlaveCard,0,sizeof(MASTER_SLAVE_CARD));
}
int getPoolAccountRole(u_short portid)
{
_prepaid_info *prepaidInfo = NULL;
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
if (shmp->caller_info.head < MSISDN_HEAD_NUM && shmp->caller_info.tail < UNIT_STORE_ACCOUNT)
{
prepaidInfo = &ramshm_ptr->prepaid_data.prepaid_info[shmp->caller_info.head][shmp->caller_info.tail];
}
if(prepaidInfo == NULL)
return MASTER_SLAVE_NONE;
return prepaidInfo->poolAccount.role;
}
static int getCosPoolRole(u_short portid)
{
//_prepaid_info *prepaidInfo = NULL;
_state_data *shmp;
u8 cosID=0;
COSTable *cosTableItem;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
cosID = GetLocalCosID(&shmp->caller_info);
cosTableItem = &ppsParam.ppsTables.cosTable[cosID];
return cosTableItem->poolAccount[0].role;
}
int masterSlaveIVRProc(u_short portid)
{
_state_data *shmp;
int result_sub = SERVICE_KEEP_STATE,result_main = SERVICE_KEEP_STATE;
MASTER_SLAVE_CARD *masterSlaveCard;
PutLogFunID("masterSlaveIVRProc");
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
if(shmp->process_info.funnel++>PROMPT_AND_COLLECT_TIMER)
{
return SERVICE_EXIT_PPS;
}
switch(getMasterSlaveState(portid))
{
case S_MASTER_SLAVE_IDLE:
clearMasterSlaveInfo(portid);
switch(getCosPoolRole(portid))
{
case MASTER_SLAVE_NONE:
playPromptVoice(portid,SERIVCE_NOT_APPLIED);
changeMasterSlaveState(portid,S_MASTER_PLAY);
break;
default:
if(getPoolAccountRole(portid) == MASTER_SLAVE_CHILD)
{
playPromptAndCollectVoice(portid,SLAVE_CARD_PROMPT,1);
changeMasterSlaveState(portid,S_SLAVE_CHOICE);
}
else
{
playPromptAndCollectVoice(portid,MASTER_CARD_PROMPT,1);
changeMasterSlaveState(portid,S_MASTER_CHOICE);
}
break;
}
break;
case S_MASTER_CHOICE:
result_sub = WaitForMasterChoice(shmp);
switch(result_sub)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
switch(getMasterSalveFunc(shmp))
{
case 0:
result_main = SERVICE_RETURN_TO_PARENT;
break;
case 1:
changeMasterSlaveState(portid,S_MASTER_INQUIRY);
break;
case 2:
if(getCosPoolRole(portid) != MASTER_SLAVE_PARENT)
{
playPromptVoice(portid,SERIVCE_NOT_APPLIED);
changeMasterSlaveState(portid,S_MASTER_PLAY);
}
else
changeMasterSlaveState(portid,S_MASTER_ADD_SLAVE);
break;
case 3:
changeMasterSlaveState(portid,S_MASTER_DEL_SLAVE);
break;
default:
result_main = SERVICE_EXIT_PPS;
break;
}
break;
case INPUT_ERROR_REINPUT:
playPromptAndCollectVoice(portid,MASTER_CARD_PROMPT,1);
break;
case INPUT_ERROR_EXIT:
result_main = SERVICE_EXIT_PPS;
break;
}
break;
case S_SLAVE_CHOICE:
result_sub = WaitForSalveChoice(shmp);
switch(result_sub)
{
case NO_INPUT:
break;
case INPUT_SUCCESS:
switch(getMasterSalveFunc((shmp)))
{
case 0:
result_main = SERVICE_RETURN_TO_PARENT;
break;
case 1:
changeMasterSlaveState(portid,S_SLAVE_INQUIRY);
break;
default:
result_main = SERVICE_EXIT_PPS;
break;
}
break;
case INPUT_ERROR_REINPUT:
playPromptAndCollectVoice(portid,SLAVE_CARD_PROMPT,1);
break;
case INPUT_ERROR_EXIT:
result_main = SERVICE_EXIT_PPS;
break;
}
break;
case S_MASTER_INQUIRY:
result_sub = masterEnquiryProc(portid);
switch(result_sub)
{
case SERVICE_KEEP_STATE:
break;
case SERVICE_RETURN_TO_PARENT:
changeMasterSlaveState(portid,S_MASTER_SLAVE_IDLE);
break;
case SERVICE_EXIT_PPS:
default:
result_main = SERVICE_EXIT_PPS;
break;
}
break;
case S_SLAVE_INQUIRY:
result_sub = slaveEnquiryProc(portid);
switch(result_sub)
{
case SERVICE_KEEP_STATE:
break;
case SERVICE_RETURN_TO_PARENT:
changeMasterSlaveState(portid,S_MASTER_SLAVE_IDLE);
break;
case SERVICE_EXIT_PPS:
default:
result_main = SERVICE_EXIT_PPS;
break;
}
break;
case S_MASTER_ADD_SLAVE:
result_sub = masterAddProc(portid);
switch(result_sub)
{
case SERVICE_KEEP_STATE:
break;
case SERVICE_RETURN_TO_PARENT:
changeMasterSlaveState(portid,S_MASTER_SLAVE_IDLE);
break;
case SERVICE_EXIT_PPS:
default:
result_main = SERVICE_EXIT_PPS;
break;
}
break;
case S_MASTER_DEL_SLAVE:
result_sub = masterDelProc(portid);
switch(result_sub)
{
case SERVICE_KEEP_STATE:
break;
case SERVICE_RETURN_TO_PARENT:
changeMasterSlaveState(portid,S_MASTER_SLAVE_IDLE);
break;
case SERVICE_EXIT_PPS:
default:
result_main = SERVICE_EXIT_PPS;
break;
}
break;
case S_MASTER_PLAY:
result_sub = CallingCardWaitingForSpecialResourceReport(shmp);
if(result_sub == SERVICE_KEEP_STATE)
break;
else if(result_sub == 1)
{
result_main = SERVICE_RETURN_TO_PARENT;
}
else
result_main = SERVICE_EXIT_PPS;
break;
}
return result_main;
}
static int fillTransferStateData(_state_data *shmp,_account_info *masterAccount,_account_info *childAccount,float fee)
{
shmp->process_info.ppsService.feeTransfer.fee = fee;
memcpy(&shmp->caller_info,masterAccount,sizeof(_account_info));
if(GetAccountPos(&shmp->caller_info) == FALSE)
return -1;
memcpy(&shmp->process_info.ppsService.feeTransfer.account,childAccount,sizeof(_account_info));
if(GetAccountPos(&shmp->process_info.ppsService.feeTransfer.account) == FALSE)
return -1;
return 1;
}
static int childAutoTransferInFromMaster(_prepaid_info *slave)
{
int cos_id=0,rst;
COSTable *cosTableItem;
_prepaid_info *master;
_account_info masterAccount,childAccount;
u8 *msisdnBCD,len;
float transferFee,diff;
COS_Pool_Account *pA;
if(slave->poolAccount.role != MASTER_SLAVE_CHILD)
return 0;
memset(&masterAccount,0,sizeof(_account_info));
msisdnBCD = slave->poolAccount.roleParty.child.parentMsisdn;
len = msisdnBCD[MAX_MSISDN_BLEN-1];
BcdToAscii((char *)masterAccount.number,msisdnBCD,18);
StringCut((char *)masterAccount.number,'F');
masterAccount.number[len] = 0;
if(GetAccountPos(&masterAccount) == FALSE)
return -1;
memset(&childAccount,0,sizeof(_account_info));
msisdnBCD = slave->msisdn;
len = msisdnBCD[MAX_MSISDN_BLEN-1];
BcdToAscii((char *)childAccount.number,msisdnBCD,18);
StringCut((char *)childAccount.number,'F');
childAccount.number[len] = 0;
if((master = getPrepaidInfo(&masterAccount)) == NULL)
return -1;
cos_id = slave->cos_id%MaxCosTableItem;
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
pA = &cosTableItem->poolAccount[0];
transferFee = pA->roleParty.child.maxFeePerDay;
#ifdef OCS_USE_REDIS_DB
OCS_usr_redis usr_redis;
RedisGetUserBalance(slave, &usr_redis);
if(isPromotionCanBeTransfered(&masterAccount) == TRUE)
diff = transferFee - (usr_redis.usr_balance + usr_redis.pro_balance);
else
diff = transferFee - usr_redis.usr_balance;
#else
if(isPromotionCanBeTransfered(&masterAccount) == TRUE)
diff = transferFee - (slave->balance+slave->promo_balance);
else
diff = transferFee - slave->balance;
#endif
rst = checkTransferedPartialFee(&masterAccount,diff);
switch(rst)
{
case CHECK_TRANSFERED_FEE_OK:
break;
case CHECK_TRANSFERED_FEE_INSUFFIENT:
pps_print_error(0,"%s insufficient fee",masterAccount.number);
return -1;
break;
case CHECK_TRANSFERED_FEE_EXPIERED:
pps_print_error(0,"%s expired",masterAccount.number);
return -1;
break;
}
if(GetAccountPos(&childAccount) == FALSE)
return -1;
poolTransferAccount(&masterAccount,&childAccount,diff);
SendTransferCDR(&masterAccount,&childAccount,-diff);
SendTransferCDR(&childAccount,&masterAccount,diff);
return 2;
}
static int checkMasterFee(u_short portid)
{
//_prepaid_info *prepaidInfo;
_state_data *shmp;
MASTER_SLAVE_ADD *add;
u8 cosID;
COSTable *cosTableItem;
COS_Pool_Account *pA;
float transferFee,slaveAddFee;
int rst;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add;
cosID = getAddingSlaveCosId(shmp,add);
cosTableItem = &ppsParam.ppsTables.cosTable[cosID];
pA = &cosTableItem->poolAccount[0];
transferFee = pA->roleParty.child.maxFeePerDay;
slaveAddFee = getAddSlaveCharge(&shmp->caller_info);
rst = checkTransferedPartialFee(&shmp->caller_info,transferFee+slaveAddFee);
return rst;
}
static int getAddingSlaveCosId(_state_data *shmp,MASTER_SLAVE_ADD *add)
{
int cos_id;
COSTable *cosTableItem;
cos_id = GetLocalCosID(&shmp->caller_info);
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
cos_id = cosTableItem->poolAccount[0].roleParty.parent.cosIDForChild[add->cosID%MaxCosTableItem];
return cos_id;
}
static int RealTransferToSlave(_state_data *shmp)
{
int cos_id=0,rst;
COSTable *cosTableItem;
double transferFee;
COS_Pool_Account *pA;
_prepaid_info *master,*slave;
MASTER_SLAVE_ADD *add;
_state_data newShmp;
add = &shmp->process_info.ppsService.masterSlaveCard.masterSlaveFunc.add;
if((master = getPrepaidInfo(&shmp->caller_info)) == NULL)
return -1;
if((slave = getPrepaidInfo(&add->slaveInfo)) == NULL)
return -1;
cos_id = getAddingSlaveCosId(shmp,add);
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
pA = &cosTableItem->poolAccount[0];
transferFee = pA->roleParty.child.maxFeePerDay;
rst = fillTransferStateData(&newShmp,&shmp->caller_info,&add->slaveInfo,transferFee);
if(rst < 0)
return -1;
FeeTransferTransaction(&newShmp);
return 2;
}
static int smppNotifyParentTransfer(_prepaid_info *slave)
{
u8 *msisdnBCD,len;
u8 masterNumber[2*MAX_MSISDN_BLEN],slaveNumber[2*MAX_MSISDN_BLEN];
u_char msg[MAX_SMS_LEN*4]={0};
memset(masterNumber,0,2*MAX_MSISDN_BLEN);
msisdnBCD = slave->poolAccount.roleParty.child.parentMsisdn;
len = msisdnBCD[MAX_MSISDN_BLEN-1];
BcdToAscii((char *)masterNumber,msisdnBCD,18);
StringCut((char *)masterNumber,'F');
masterNumber[len] = 0;
memset(slaveNumber,0,2*MAX_MSISDN_BLEN);
msisdnBCD = slave->msisdn;
len = msisdnBCD[MAX_MSISDN_BLEN-1];
BcdToAscii((char *)slaveNumber,msisdnBCD,18);
StringCut((char *)slaveNumber,'F');
slaveNumber[len] = 0;
strcpy((char *)msg, (char *)slaveNumber);
strcat((char *)msg," ");
strcat((char *)msg, (char *)getSmsSentenceNative(0,SMS_POOL_CHILD_LOW_FEE));
return smppSendMOSM((char *)masterNumber, (char *)ppsParam.ppsTables.serviceNumber[FeeTransferPosition].number
,msg,strlen((char *)msg),0);
}
static int getSlaveRechargeType(int cos_id)
{
COSTable *cosTableItem;
COS_Pool_Account *pA;
cos_id = cos_id%MaxCosTableItem;
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
pA = & cosTableItem->poolAccount[0];
return pA->roleParty.child.periodicTransferOrAutoByParent;
}
static BOOL isSlaveNeedTransferFee(_prepaid_info *slave)
{
int cos_id=0;
COSTable *cosTableItem;
COS_Pool_Account *pA;
double transferFee;
cos_id = slave->cos_id%MaxCosTableItem;
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
pA = &cosTableItem->poolAccount[0];
transferFee = pA->roleParty.child.maxFeePerDay;
#ifdef OCS_USE_REDIS_DB
OCS_usr_redis usr_redis;
RedisGetUserBalance(slave, &usr_redis);
if(usr_redis.usr_balance + usr_redis.pro_balance >= transferFee)
#else
if(slave->balance + slave->promo_balance >= transferFee)
#endif
return FALSE;
return TRUE;
}
void resetPoolSlaveDaily(u_short head,u_short tail)
{
_prepaid_data *shmp=&ramshm_ptr->prepaid_data;
_prepaid_info *slave;
slave = &shmp->prepaid_info[head][tail];
if(slave->poolAccount.role != MASTER_SLAVE_CHILD)
return;
slave->poolAccount.roleParty.child.callsToday = 0;
slave->poolAccount.roleParty.child.smsToday = 0;
slave->poolAccount.roleParty.child.chargedToday = 0;
if(isSlaveNeedTransferFee(slave) == FALSE)
return;
switch(getSlaveRechargeType(slave->cos_id))
{
case 0:
childAutoTransferInFromMaster(slave);
break;
case 1:
default:
smppNotifyParentTransfer(slave);
break;
}
}
int isPoolChildReachCallLimit(_state_data *shmp)
{
int cos_id=0;
COSTable *cosTableItem;
COS_Pool_Account *pA;
_prepaid_info *slave=NULL;
if(shmp->caller_info.fee == 0)
return 0;
if (shmp->caller_info.head < MSISDN_HEAD_NUM
&& shmp->caller_info.tail < UNIT_STORE_ACCOUNT)
{
slave = &ramshm_ptr->prepaid_data.prepaid_info[shmp->caller_info.head][shmp->caller_info.tail];
}
if(slave == NULL)
return 0;
if(slave->poolAccount.role != MASTER_SLAVE_CHILD)
return 0;
cos_id = slave->cos_id%MaxCosTableItem;
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
pA = & cosTableItem->poolAccount[0];
if(slave->poolAccount.roleParty.child.callsToday >= pA->roleParty.child.maxCallsPerDay)
return 1;
if(getConsumeFee(slave) >= pA->roleParty.child.maxFeePerDay)
return 2;
return 0;
}
int isPoolChildReachSMSLimit(_state_data *shmp)
{
int cos_id=0;
COSTable *cosTableItem;
COS_Pool_Account *pA;
_prepaid_info *slave=NULL;
if(shmp->caller_info.fee == 0)
return 0;
if (shmp->caller_info.head < MSISDN_HEAD_NUM
&& shmp->caller_info.tail < UNIT_STORE_ACCOUNT)
{
slave = &ramshm_ptr->prepaid_data.prepaid_info[shmp->caller_info.head][shmp->caller_info.tail];
}
if(slave == NULL)
return 0;
if(slave->poolAccount.role != MASTER_SLAVE_CHILD)
return 0;
cos_id = slave->cos_id%MaxCosTableItem;
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
pA = & cosTableItem->poolAccount[0];
if(slave->poolAccount.roleParty.child.smsToday >= pA->roleParty.child.maxSMSPerDay)
return 1;
if(getConsumeFee(slave) >= pA->roleParty.child.maxFeePerDay)
return 2;
return 0;
}
int isPoolChildReachFeeLimit(_account_info *ptr)
{
int cos_id=0;
COSTable *cosTableItem;
COS_Pool_Account *pA;
_prepaid_info *slave=NULL;
if(ptr->fee == 0)
return 0;
if (ptr->head < MSISDN_HEAD_NUM
&& ptr->tail < UNIT_STORE_ACCOUNT)
{
slave = &ramshm_ptr->prepaid_data.prepaid_info[ptr->head][ptr->tail];
}
if(slave == NULL)
return 0;
if(slave->poolAccount.role != MASTER_SLAVE_CHILD)
return 0;
cos_id = slave->cos_id%MaxCosTableItem;
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
pA = & cosTableItem->poolAccount[0];
if(getConsumeFee(slave) >= pA->roleParty.child.maxFeePerDay)
return 2;
return 0;
}
void increPoolChildCalls(_account_info *ptr)
{
_prepaid_info *slave=NULL;
DWORD instance;
if (ptr->head < MSISDN_HEAD_NUM
&& ptr->tail < UNIT_STORE_ACCOUNT)
{
slave = &ramshm_ptr->prepaid_data.prepaid_info[ptr->head][ptr->tail];
}
if(slave == NULL)
return;
if(slave->poolAccount.role != MASTER_SLAVE_CHILD)
return;
slave->poolAccount.roleParty.child.callsToday++;
instance = ptr->head * UNIT_STORE_ACCOUNT + ptr->tail;
SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT);
}
void increPoolChildSMS(_account_info *ptr)
{
_prepaid_info *slave=NULL;
DWORD instance;
if (ptr->head < MSISDN_HEAD_NUM
&& ptr->tail < UNIT_STORE_ACCOUNT)
{
slave = &ramshm_ptr->prepaid_data.prepaid_info[ptr->head][ptr->tail];
}
if(slave == NULL)
return;
if(slave->poolAccount.role != MASTER_SLAVE_CHILD)
return;
slave->poolAccount.roleParty.child.smsToday++;
instance = ptr->head * UNIT_STORE_ACCOUNT + ptr->tail;
SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT);
}
void increPoolChildCharged(_account_info *ptr,double charged)
{
_prepaid_info *slave=NULL;
if (ptr->head < MSISDN_HEAD_NUM
&& ptr->tail < UNIT_STORE_ACCOUNT)
{
slave = &ramshm_ptr->prepaid_data.prepaid_info[ptr->head][ptr->tail];
}
if(slave == NULL)
return;
if(slave->poolAccount.role != MASTER_SLAVE_CHILD)
return;
slave->poolAccount.roleParty.child.chargedToday += charged;
}
static int isChildRechargeAllowed(_prepaid_info *prepaidInfo)
{
COSTable *cosTableItem;
COS_Pool_Account *pA;
int cos_id;
cos_id = prepaidInfo->cos_id%MaxCosTableItem;
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
pA = &cosTableItem->poolAccount[0];
if(pA->roleParty.child.isRechargeAllowed)
return TRUE;
return FALSE;
}
int isChildTransferAllowed(_prepaid_info *prepaidInfo)
{
COSTable *cosTableItem;
COS_Pool_Account *pA;
int cos_id;
cos_id = prepaidInfo->cos_id%MaxCosTableItem;
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
pA = &cosTableItem->poolAccount[0];
if(pA->roleParty.child.isTransferAllowed)
return TRUE;
return FALSE;
}
int isTransferAllowed(u_short portid)
{
_prepaid_info *prepaidInfo;
_state_data *shmp;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL)
return FALSE;
if(prepaidInfo->poolAccount.role == MASTER_SLAVE_CHILD)
return isChildTransferAllowed(prepaidInfo);
GetAccountPos(&shmp->caller_info);
if(GetAccountStatus(&shmp->caller_info) != T_NORMAL)
return FALSE;
return TRUE;
}
int isRechargeAllowed(u_short portid)
{
_prepaid_info *prepaidInfo;
_state_data *shmp;
int rst;
return TRUE;
shmp = (_state_data *)&smshm_ptr->state_data;
shmp += portid;
if((prepaidInfo = getPrepaidInfo(&shmp->caller_info)) == NULL)
return FALSE;
if(prepaidInfo->poolAccount.role == MASTER_SLAVE_CHILD)
{
rst = isChildRechargeAllowed(prepaidInfo);
if(rst == FALSE)
{
pps_print_error(shmp->process_info.logMsisdn,"[%05d]slave card ,recharge not allowed",portid);
}
return rst;
}
return TRUE;
}
static int smppNotifyMasterADD(u_char *masterNumber,u_char *slaveNumber)
{
char msg[MAX_SMS_LEN*4]={0};
char dayTimeReadable[32]={0};
ppsgetdaytime_readFormat(dayTimeReadable);
strcpy(msg, (char *)getSmsSentenceNative(0,SMS_POOL_ADDED_CHILD));
cliManipulationFunction((char *)slaveNumber, (char *)masterNumber );
strcat(msg, (char *)slaveNumber);
strcat(msg," ");
strcat(msg, (char *)getSmsSentenceNative(0,SMS_ON));
strcat(msg," ");
strcat(msg, dayTimeReadable);
return smppSendMOSM((char *)masterNumber, (char *)ppsParam.ppsTables.serviceNumber[PoolAccountPosition].number, (u_char *)msg,strlen(msg),0);
}
static int smppNotifyMasterDEL(u_char *masterNumber,u_char *slaveNumber)
{
char msg[MAX_SMS_LEN*4]={0};
char dayTimeReadable[32]={0};
ppsgetdaytime_readFormat(dayTimeReadable);
strcpy(msg, (char *)getSmsSentenceNative(0,SMS_POOL_DELED_CHILD));
cliManipulationFunction((char *)slaveNumber, (char *)masterNumber );
strcat(msg, (char *)slaveNumber);
strcat(msg," ");
strcat(msg, (char *)getSmsSentenceNative(0,SMS_ON));
strcat(msg," ");
strcat(msg, dayTimeReadable);
return smppSendMOSM((char *)masterNumber, (char *)ppsParam.ppsTables.serviceNumber[PoolAccountPosition].number, (u_char *)msg,strlen(msg),0);
}
static int smppNotifySlaveADD(u_char *masterNumber,u_char *slaveNumber)
{
char msg[MAX_SMS_LEN*4]={0};
char dayTimeReadable[32]={0};
ppsgetdaytime_readFormat(dayTimeReadable);
strcpy(msg, (char *)getSmsSentenceNative(0,SMS_POOL_BEEN_ADDED_CHILD));
cliManipulationFunction((char *)masterNumber, (char *)slaveNumber );
strcat(msg, (char *)masterNumber);
strcat(msg," ");
strcat(msg, (char *)getSmsSentenceNative(0,SMS_ON));
strcat(msg," ");
strcat(msg, dayTimeReadable);
return smppSendMOSM((char *)slaveNumber, (char *)ppsParam.ppsTables.serviceNumber[PoolAccountPosition].number, (u_char *)msg,strlen(msg),0);
}
static int smppNotifySlaveDEL(u_char *masterNumber,u_char *slaveNumber)
{
char msg[MAX_SMS_LEN*4]={0};
char dayTimeReadable[32]={0};
ppsgetdaytime_readFormat(dayTimeReadable);
strcpy(msg, (char *)getSmsSentenceNative(0,SMS_POOL_BEEN_DELED_CHILD));
cliManipulationFunction((char *)masterNumber, (char *)slaveNumber );
strcat(msg, (char *)masterNumber);
strcat(msg," ");
strcat(msg, (char *)getSmsSentenceNative(0,SMS_ON));
strcat(msg," ");
strcat(msg, dayTimeReadable);
return smppSendMOSM((char *)slaveNumber, (char *)ppsParam.ppsTables.serviceNumber[PoolAccountPosition].number, (u_char *)msg,strlen(msg),0);
}
void ppsgetdaytime_readFormat(char *daytime_buf)
{
struct tm *t,tt;
long curr_time;
t=&tt;
curr_time=time((long *)0);
t=localtime(&curr_time);
sprintf(daytime_buf,"%04d-%02d-%02d %02d:%02d:%02d",
t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour,
t->tm_min, t->tm_sec);
daytime_buf[19] = 0;
}
static int getAddSlaveCharge(_account_info *accountInfo)
{
int head,tail;
int tariff_id=0;
head = accountInfo->head;
tail = accountInfo->tail;
if(head>=MSISDN_HEAD_NUM)
return 0;
tariff_id = GetAccountZoneID(head,tail);
if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0;
return ramshm_ptr->tariff_data.comm_tariff[tariff_id].childChangeChargeAmount;
}
int increMasterChangeCounter(_prepaid_info *prepaidInfo)
{
u_char *times;
if(prepaidInfo == NULL)
return 0;
PutLogFunID("increMasterChangeCounter");
times = &prepaidInfo->poolAccount.roleParty.parent.changeTimes;
if(*times<0x7F)
return (++(*times));
return *times;
}
int IncreasePoolAccountChangeCounter(int head, int tail)
{
PutLogFunID("IncreasePoolAccountChangeCounter");
if(head<MSISDN_HEAD_NUM)
{
return increMasterChangeCounter(&ramshm_ptr->prepaid_data.prepaid_info[head][tail]);
}
return 0;
}
extern void SendManualOperationCDR(_account_info *caller_info, _account_info *called_info, int charge);
int masterChangeSlaveCharge(_state_data *shmp,_account_info *slaveInfo)
{
int head,tail;
int amount,times;
_prepaid_info *ptr;
COSTable *cosTableItem;
int cos_id;
PutLogFunID("masterChangeSlaveCharge");
head = shmp->caller_info.head;
tail = shmp->caller_info.tail;
if(head>=MSISDN_HEAD_NUM)
return 0;
ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail];
cos_id = ptr->cos_id%MaxCosTableItem;
cosTableItem = &ppsParam.ppsTables.cosTable[cos_id];
if(!cosTableItem->serviceControl[0].poolAccountChangeChargeFlag)
return 0;
IncreasePoolAccountChangeCounter(head,tail);
times = cosTableItem->serviceControl[0].poolAccountFreeChangeTimes;
if(ptr->poolAccount.roleParty.parent.changeTimes <= times)
return 0;
amount = getAddSlaveCharge(&shmp->caller_info);
#ifdef OCS_USE_REDIS_DB
OCS_usr_redis usr_redis;
RedisGetUserBalance(ptr, &usr_redis);
ptr->balance = usr_redis.usr_balance;
usr_redis.usr_balance -= amount;
RedisUpdateUserField(&usr_redis, OCS_REDIS_FIELD_BALANCE);
#endif
ptr->balance -= amount;
SendManualOperationCDR(&shmp->caller_info,&shmp->called_info,-amount);
return amount;
}
int BillingChildNumberChange(_state_data *shmp)
{
int head,tail;
int amount,tariff_id=0;
_prepaid_info *ptr;
PutLogFunID("BillingChildNumberChange");
head = shmp->caller_info.head;
tail = shmp->caller_info.tail;
if(head>=MSISDN_HEAD_NUM)
return 0;
tariff_id = GetAccountZoneID(head,tail);
if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0;
ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail];
amount = ramshm_ptr->tariff_data.comm_tariff[tariff_id].childChangeChargeAmount;
#ifdef OCS_USE_REDIS_DB
OCS_usr_redis usr_redis;
RedisGetUserField(&ramshm_ptr->prepaid_data.prepaid_info[head][tail], &usr_redis, OCS_REDIS_FIELD_BALANCE);
ptr->balance = usr_redis.usr_balance;
usr_redis.usr_balance -= amount;
RedisUpdateUserField(&usr_redis, OCS_REDIS_FIELD_BALANCE);
#endif
ptr->balance = ptr->balance - amount;
shmp->caller_info.charge = amount;
return 1;
}
int CheckWetherPoolNumber(_account_info *caller, _account_info *called)
{
int i,len;
char msisdn[32];
UserData_Pool_Account *poolAccount;
_prepaid_data *shmp=&ramshm_ptr->prepaid_data;
PutLogFunID("CheckWetherPoolNumber");
poolAccount = &shmp->prepaid_info[caller->head][caller->tail].poolAccount;
if(caller->head < MSISDN_HEAD_NUM && caller->tail <UNIT_STORE_ACCOUNT)
{
if(poolAccount->role == MASTER_SLAVE_CHILD)
{
len = poolAccount->roleParty.child.parentMsisdn[MAX_MSISDN_BLEN-1];
if(len>MAX_MSISDN_ALEN || len<2)
return FALSE;
BcdToAscii(msisdn,poolAccount->roleParty.child.parentMsisdn,MAX_MSISDN_ALEN);
msisdn[len] = 0;
CutUnknownPrefix(msisdn);
if(strcmp(msisdn, (char *)called->number)==0)
return TRUE;
}
else if(poolAccount->role == MASTER_SLAVE_PARENT)
{
if(!poolAccount->roleParty.parent.childNumber)
return NOT_FAVORITE_NUMBER;
for(i=0;i<POOL_MAX_CHILD;i++)
{
len = poolAccount->roleParty.parent.childMsisdn[i][MAX_MSISDN_BLEN-1];
if(len>MAX_MSISDN_ALEN || len<2)
continue;
BcdToAscii(msisdn,poolAccount->roleParty.parent.childMsisdn[i],MAX_MSISDN_ALEN);
msisdn[len] = 0;
CutUnknownPrefix(msisdn);
if(strcmp(msisdn, (char *)called->number)==0)
return TRUE;
}
}
else
return FALSE;
}
return FALSE;
}
void ChangeTariffToPoolCallTariff(_state_data *shmp,_bill_tariff *ptar)
{
u_short rUnit=60;
float rAmount=0;
u_short Unit=0;
u_char tier;
int tariff_id;
PutLogFunID("ChangeTariffToPoolCallTariff");
tariff_id = shmp->caller_info.location;
Unit = ptar->unit_time;
if(Unit == 0) Unit = 60;
if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0;
rUnit = ramshm_ptr->tariff_data.comm_tariff[tariff_id].poolAccountChargeUnit;
rAmount = ramshm_ptr->tariff_data.comm_tariff[tariff_id].poolAccountChargeAmount;
if(rUnit ==0) rUnit = 60;
tier = getCurrentTier(shmp,ptar);
ptar->tierRating.rating[tier].base_fee = Unit * rAmount /rUnit;
}