#include "../include/includes.h" #include "../include/ramdata.h" #include "../include/message.h" #include "../include/ppsm.h" #include "../include/crypt.h" #include "../include/ppsoid.h" #include "../include/cdrme.h" #include "../include/param.h" //#include "../include/mfunc.h" #include "../include/plat_inc.h" #include "../../../../plat/scf/src/include/scfmsg.h" /*------------------------------------------------*/ extern _state_machine *smshm_ptr; extern _tariff_private *blf_shmp; extern _ram_data *ramshm_ptr; extern _debug_info *debug_shmp; extern int csta_now_instance,csta_old_instance; extern int logMsgFlag; extern struct timeval tvnow; /*------------------------------------------------*/ extern PPSParamStruct ppsParam; /*------------------------------------------------*/ extern int FindPPSSubsStoreIndex(); extern int AccountLatchFlagCheck(); extern int GetRechargeCardValidTime(); extern int GetRechargeCardFaceValue(); extern int IsPSTNMaitenance(); extern int IsVMSDeposit(); extern int IsCallingCardNumber(char *number); //extern int des(); extern void SendAccountRealSync_2(_account_info *accountInfo, double balance, double promotion, int ocode); extern void increPoolChildCharged(_account_info *ptr,double charged); extern void increPoolChildSMS(_account_info *ptr); extern void increPoolChildCalls(_account_info *ptr); extern BOOL isPromotionCanBeUsedAtThisPoint(_state_data *shmp); extern float BillingFormula(_state_data *shmp,_bill_tariff *ptar,int startTime); extern float TimeToCharge(_state_data *shmp,_bill_tariff *ptar, int duration,int begin_time, int init_bill); extern double GetBalanceWithPromotionControl(_state_data *stateProc,_account_info *ptr); extern float caculateMiniCharge(_state_data *shmp,_bill_tariff *ptar); extern int preLeftTime(_state_data *shmp,float balance,_bill_tariff *ptar); extern void PPSSendUserSMSNotification(int head, int tail,char *msgSend); extern u_char getCurrentTier(_state_data *shmp,_bill_tariff *ptar); extern void ChangeTariffToPoolCallTariff(_state_data *shmp,_bill_tariff *ptar); extern float getCurrentFee(_state_data *shmp); extern int isPoolChildReachSMSLimit(_state_data *shmp); extern char *sendPPSNotificationMessage(int head, int tail, int sms_id); extern u_char *getSmsSentenceNative(SMS_SENTENCE id,u8 languageType); extern BYTE ChangeUserCategory(BYTE *msisdn,BYTE type); extern int subscribe_bundle_plan_send_used_up_info(char *caller_number, SMS_SENTENCE id); extern void pps_print_error(u_char logMsisdnFlag,const char *fmt, ...); extern int reportGprsCDRIncrement(int duration, float charge, long gprsVolume); float GetAccountBalance(int head, int tail); int isPoolChildReachFeeLimit(_account_info *ptr); /*------------------------------------------------*/ int GetMOTariffData(_state_data *shmp,_bill_tariff *ptar, char *call_no, int zone_id) { int len=0,maxlen=0,msisdn_len; int loop,index=-1; _bill_tariff *ptr; PutLogFunID("GetMOTariffData"); msisdn_len = strlen(call_no); if (zone_id >= MAX_ZONE_NUM || zone_id <0) zone_id = 0; if(ppsParam.serviceControl.cos_group_flag)// only use one type of tariff table in specify system {// search by tree in this kind of tariff table if(zone_id>=MAX_ZONE_NUM_NEW) { DebugMsg(debugmib.display.asciiOut, "search prefix failed: zone id = %d, called_no=%s", zone_id,call_no); return 0; } index = pps_get_charge_prefix(zone_id, call_no);// search tariff table by prefix of called number if(index>=0) { ptr = &blf_shmp->bill_tariff[index/BILLING_BASE_NUM][index%BILLING_BASE_NUM]; memcpy(ptar,ptr,sizeof(_bill_tariff));// cpy content of tariff table if(shmp != NULL)// save address of table { shmp->process_info.tariffMoReadOnly = &blf_shmp->bill_tariff[index/BILLING_BASE_NUM][index%BILLING_BASE_NUM]; } return 1; } else return 0; /* for(loop0=0;loop0bill_tariff[zone_id][loop]; len = strlen(ptr->bill_id); if(len == 0) break; if(len>maxlen && len<=msisdn_len) { if(!strncasecmp(call_no,ptr->bill_id,len)) { maxlen = len; index = loop; } } } } */ } else {// for this kind of tariff table, has 16 sub items; each has 1024 records for(loop=0;loopbill_tariff[zone_id][loop]; len = strlen(ptr->bill_id); if(len == 0) break; if(len>maxlen && len<=msisdn_len) { if(!strncasecmp(call_no,ptr->bill_id,len)) { maxlen = len; index = loop; } } } } if(index>=0) { ptr = &blf_shmp->bill_tariff[zone_id][index]; memcpy(ptar,ptr,sizeof(_bill_tariff)); if(shmp != NULL) { shmp->process_info.tariffMoReadOnly = &blf_shmp->bill_tariff[zone_id][index]; } return 1; } return FALSE; } int IsNormalAccount(_account_info *ptr) { if(ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { return TRUE; } return FALSE; } int GetAccountFavoriteNumberCounter(_account_info *ptr) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; if(ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { return shmp->prepaid_info[ptr->head][ptr->tail].favorite_numbers; }else { return -1; } } int StoreAccountFavoriteNumber(_account_info *ptr,char *msisdn,int index) { int i,len; _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("StoreAccountFavoriteNumber"); if(index>0 && index<=MAX_FAVORITE_NUMBERS) { len = strlen(msisdn); shmp->prepaid_info[ptr->head][ptr->tail].favorite_number[index-1][MAX_MSISDN_BLEN-1] = len; if(len%2==1) len ++; AsciiToBcd(shmp->prepaid_info[ptr->head][ptr->tail].favorite_number[index-1],msisdn,len); return index; } if(ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { for(i=0;iprepaid_info[ptr->head][ptr->tail].favorite_number[i][MAX_MSISDN_BLEN-1]<3) { len = strlen(msisdn); shmp->prepaid_info[ptr->head][ptr->tail].favorite_number[i][MAX_MSISDN_BLEN-1] = len; if(len%2==1) len ++; AsciiToBcd(shmp->prepaid_info[ptr->head][ptr->tail].favorite_number[i],msisdn,len); shmp->prepaid_info[ptr->head][ptr->tail].favorite_numbers++; if(shmp->prepaid_info[ptr->head][ptr->tail].favorite_numbers>MAX_FAVORITE_NUMBERS) shmp->prepaid_info[ptr->head][ptr->tail].favorite_numbers=MAX_FAVORITE_NUMBERS; return (i+1); } } return (i+1); }else { return -1; } } int GetAccountFavoriteNumber(_account_info *ptr,char *msisdn,u_char index) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; int len; PutLogFunID("GetAccountFavoriteNumber"); if(index<=MAX_FAVORITE_NUMBERS && index>0) { len = shmp->prepaid_info[ptr->head][ptr->tail].favorite_number[index-1][MAX_MSISDN_BLEN-1]; if(len<3 || len>16) { return 0; } memcpy(msisdn, shmp->prepaid_info[ptr->head][ptr->tail].favorite_number[index-1], MAX_MSISDN_BLEN); return index; } return 0; } int GetAccountPos(_account_info *ptr) { int len=0,store_index; char msisdn[32]; PutLogFunID("GetAccountPos"); len = strlen((char *)ptr->number); strcpy(msisdn, (char *)ptr->number); if(lenMAX_MSISDN_ALEN) { ptr->head = MSISDN_HEAD_NUM + 1; ptr->tail = UNIT_STORE_ACCOUNT + 1; return FALSE; } store_index = FindPPSSubsStoreIndex(atoll((char *)ptr->number)); if(store_index<0) { ptr->head = MSISDN_HEAD_NUM + 1; ptr->tail = UNIT_STORE_ACCOUNT + 1; return FALSE; } ptr->head = store_index / UNIT_STORE_ACCOUNT; ptr->tail = store_index % UNIT_STORE_ACCOUNT; return TRUE; } int GetUserInstance(long long head,int *instance) { int loop; _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetUserInstance"); for(loop=0;loopmsisdn_head[loop]) { *instance = loop ; return 1; } } return 0; } int GetUserPos(int *head,long long head1) { int loop; _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetUserPos"); for(loop=0;loopmsisdn_head[loop] !=0) if(head1 == shmp->msisdn_head[loop]) { *head = loop; return 1; } } for(loop=0;loopmsisdn_head[loop] == 0) { *head = loop; return 2; } } return 0; } float GetBalance(_account_info *ptr) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetBalance"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT){ if(shmp->prepaid_info[ptr->head][ptr->tail].balance>=ppsParam.serviceControl.maxBalance) shmp->prepaid_info[ptr->head][ptr->tail].status = T_SUSPEND; if(shmp->prepaid_info[ptr->head][ptr->tail].msisdn[MAX_MSISDN_BLEN-1]<=2) return 0; return (shmp->prepaid_info[ptr->head][ptr->tail].balance + shmp->prepaid_info[ptr->head][ptr->tail].promo_balance); } return 0; } long GetExpiration(_account_info *ptr) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetExpiration"); return (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) ? shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date : (tvnow.tv_sec+1); } long GetIncomingExpiration(_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].mt_expiration_date : (tvnow.tv_sec+1); } int GetOverdraft(_account_info *ptr) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetOverdraft"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { return shmp->prepaid_info[ptr->head][ptr->tail].overdraft; } return 0; } int IsPromotionExpired(_account_info *ptr) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("IsPromotionExpired"); if(ptr == NULL) return 0; if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { if(shmp->prepaid_info[ptr->head][ptr->tail].promo_date > tvnow.tv_sec) return 0; } return 1; } int GetCMBTimes(_account_info *ptr) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetCMBTimes"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { return shmp->prepaid_info[ptr->head][ptr->tail].callMeBackRequestTimes; } return 0; } int UpdateCMBTimes(_account_info *ptr,int times) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("UpdateCMBTimes"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { shmp->prepaid_info[ptr->head][ptr->tail].callMeBackRequestTimes += times; SendAccountRealSync_2(ptr,0.0,0.0,OMC_OCODE_EDIT); return 1; } return -1; } int resetCMBTimes(_account_info *ptr) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("resetCMBTimes"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { shmp->prepaid_info[ptr->head][ptr->tail].callMeBackRequestTimes = 0; return 1; } return -1; } void UpdateBalanceForRecharge(_account_info *ptr, int charge) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("UpdateBalanceForRecharge"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { shmp->prepaid_info[ptr->head][ptr->tail].balance = shmp->prepaid_info[ptr->head][ptr->tail].balance + charge; if(shmp->prepaid_info[ptr->head][ptr->tail].balance >= 0) shmp->prepaid_info[ptr->head][ptr->tail].overdraft = 0; /* clear overdraft for each recharge */ } } void UpdateBalance(_state_data *stateProc,_account_info *ptr, float charge,CHARGED_FEE *chargeFee) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; u_char cos_id; COSTable *cosTableItem; double promo_balance,balance; double chargedBalance = 0,chargedPromotion = 0; PutLogFunID("UpdateBalance"); cos_id = ptr->cos_id%MaxCosTableItem; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { if(charge < 0 && shmp->prepaid_info[ptr->head][ptr->tail].promo_balance > 0 && isPromotionCanBeUsedAtThisPoint(stateProc)) { promo_balance = shmp->prepaid_info[ptr->head][ptr->tail].promo_balance; promo_balance = promo_balance + charge; shmp->prepaid_info[ptr->head][ptr->tail].promo_balance = promo_balance; chargedPromotion = charge; } else { balance = shmp->prepaid_info[ptr->head][ptr->tail].balance; balance = balance + charge; shmp->prepaid_info[ptr->head][ptr->tail].balance = balance; chargedBalance = charge; } if(shmp->prepaid_info[ptr->head][ptr->tail].promo_balance<0) { chargedPromotion += shmp->prepaid_info[ptr->head][ptr->tail].promo_balance; chargedBalance -= shmp->prepaid_info[ptr->head][ptr->tail].promo_balance; shmp->prepaid_info[ptr->head][ptr->tail].balance += shmp->prepaid_info[ptr->head][ptr->tail].promo_balance; shmp->prepaid_info[ptr->head][ptr->tail].promo_balance = 0; } if((shmp->prepaid_info[ptr->head][ptr->tail].balance + shmp->prepaid_info[ptr->head][ptr->tail].overdraft)<=0) { if(cosTableItem->accountValidity[0].actionAfterBalanceDepleted) { if(shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date> (tvnow.tv_sec + cosTableItem->accountValidity[0].validDaysChangeTo*24*3600)) { shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = tvnow.tv_sec + cosTableItem->accountValidity[0].validDaysChangeTo*24*3600; } if(shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date> (tvnow.tv_sec + cosTableItem->accountValidity[0].validDaysChangeTo*24*3600)) { shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = tvnow.tv_sec + cosTableItem->accountValidity[0].validDaysChangeTo*24*3600; } } } chargeFee->balance = chargedBalance; chargeFee->promotion = chargedPromotion; increPoolChildCharged(ptr,-charge); debugmib.display.totalCharge +=charge; if(shmp->prepaid_info[ptr->head][ptr->tail].balance < 0) { if(shmp->prepaid_info[ptr->head][ptr->tail].overdraft <= 0) { shmp->prepaid_info[ptr->head][ptr->tail].balance = 0; } } } } void UpdateAccountDefaultLanguageType(_account_info *ptr, u_char type) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("UpdateAccountDefaultLanguageType"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { shmp->prepaid_info[ptr->head][ptr->tail].language_type = type; } } void UpdateAccountPIN(_account_info *ptr, char *pin) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("UpdateAccountPIN"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { memcpy(shmp->prepaid_info[ptr->head][ptr->tail].pin,pin,6); } } int GetAccountPINByMsisdn(u_char *msisdn,u_char *pin) { _account_info info; _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetAccountPINByMsisdn"); memcpy(info.number,msisdn,strlen((char *)msisdn)); info.number[strlen((char *)msisdn)] = 0; if(GetAccountPos(&info) == FALSE) return -1; if (info.head < MSISDN_HEAD_NUM && info.tail < UNIT_STORE_ACCOUNT) { memcpy(pin,shmp->prepaid_info[info.head][info.tail].pin,6); } return 1; } int CheckPINValidity(_account_info *ptr, char *pin) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("CheckPINValidity"); if(ptr->headtail< UNIT_STORE_ACCOUNT) { if(!(strncmp(shmp->prepaid_info[ptr->head][ptr->tail].pin, pin, MAX_PIN_LEN))) return 1; else return 0; } return 0; } int GetCardSystemParam(u_char cos_id,u_short faceValue) { int i; COSTable *cosTableItem; PutLogFunID("GetCardSystemParam"); cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; if(faceValue == 0) return -1; for(i=0;irechargeCardValidity[i].cardCredit == faceValue) return i; } return -1; } int GetCardSystemParamByNearestValue(u_char cos_id, u_short faceValue) { int i, ret = -1; COSTable *cosTableItem; u16 maxCredit = 0; PutLogFunID("GetCardSystemParamByNearestValue"); if (faceValue == 0) { return -1; } cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; for (i=0; irechargeCardValidity[i].cardCredit) { continue; } if (maxCredit >= cosTableItem->rechargeCardValidity[i].cardCredit) { continue; } maxCredit = cosTableItem->rechargeCardValidity[i].cardCredit; ret = i; } return ret; } void UpdateAccountCallCDR(_account_info *ptr, char *msisdn,u_long timestamp,int calltype) { int len; char buf[32]; _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("UpdateAccountCallCDR"); if(ptr->headtailprepaid_info[ptr->head][ptr->tail].last_call_type = calltype; shmp->prepaid_info[ptr->head][ptr->tail].last_call_date = timestamp; len = strlen(msisdn); if(len % 2 == 1) { strcpy(buf,msisdn); strcat(buf,"F"); ppsAsciiToBcdR(shmp->prepaid_info[ptr->head][ptr->tail].last_call_number,buf,len+1); } else { ppsAsciiToBcdR(shmp->prepaid_info[ptr->head][ptr->tail].last_call_number,msisdn,len); } shmp->prepaid_info[ptr->head][ptr->tail].last_call_number[MAX_MSISDN_BLEN-1] = len; } } void UpdateAccountLastCDR(_state_data *shmp) { int instance; PutLogFunID("UpdateAccountLastCallCDR"); switch(shmp->context_info.callType) { case CT_MO_CALL: UpdateAccountCallCDR(&shmp->caller_info, (char *)shmp->charge_info.number, shmp->cdr_info.seizuretime, LST_MO_CALL); AccountLatchFlagCheck(shmp->caller_info.head,shmp->caller_info.tail); instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); break; case CT_MT_CALL: UpdateAccountCallCDR(&shmp->called_info, (char *)shmp->charge_info.number, shmp->cdr_info.seizuretime, LST_MT_CALL); AccountLatchFlagCheck(shmp->called_info.head,shmp->called_info.tail); instance = shmp->called_info.head * UNIT_STORE_ACCOUNT + shmp->called_info.tail; SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); break; case CT_MF_CALL: UpdateAccountCallCDR(&shmp->caller_info, (char *)shmp->charge_info.number, shmp->cdr_info.seizuretime, LST_MF_CALL); AccountLatchFlagCheck(shmp->caller_info.head,shmp->caller_info.tail); instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); break; case CT_MO_SM: UpdateAccountCallCDR(&shmp->caller_info, (char *)shmp->charge_info.number, shmp->cdr_info.seizuretime, LST_MO_SMS); AccountLatchFlagCheck(shmp->caller_info.head,shmp->caller_info.tail); instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); break; } } void UpdateExpiration(_state_data *stashmp) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; long expiration = 0,i_expiration = 0; u_short valid_time, /* outgoing call */ i_valid_time, /* incoming call */ faceValue; int index,cos_id; _account_info *ptr; COSTable *cosTableItem; PutLogFunID("UpdateExpiration"); ptr = &stashmp->caller_info; if(ptr->head>=MSISDN_HEAD_NUM || ptr->tail>=UNIT_STORE_ACCOUNT) return; cos_id = shmp->prepaid_info[ptr->head][ptr->tail].cos_id; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; valid_time = GetRechargeCardValidTime(stashmp); if(valid_time<=0) valid_time = 30; i_valid_time = valid_time; faceValue = GetRechargeCardFaceValue(stashmp); expiration = shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date; i_expiration = shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date; if((index=GetCardSystemParam(cos_id,faceValue))>=0){ valid_time = cosTableItem->rechargeCardValidity[index].moValidity; i_valid_time = cosTableItem->rechargeCardValidity[index].mtValidity; } if(cosTableItem->accountValidity[0].actionAfterRecharge) { if(expiration<(valid_time*24*3600+tvnow.tv_sec)) shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = valid_time*24*60*60 + tvnow.tv_sec; if(i_expiration<(i_valid_time*24*3600+tvnow.tv_sec)) shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = i_valid_time*24*60*60 + tvnow.tv_sec; } else { if(tvnow.tv_sec > expiration) shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = valid_time*24*60*60 + tvnow.tv_sec; else{ shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date += valid_time*24*60*60; } if(tvnow.tv_sec > i_expiration) shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = i_valid_time*24*60*60 + tvnow.tv_sec; else{ shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date += i_valid_time*24*60*60; } } if(cosTableItem->accountValidity[0].maxAccountValidityDays<=0) cosTableItem->accountValidity[0].maxAccountValidityDays = 730; if(shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date> tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; if(shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date> tvnow.tv_sec +cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; } void UpdateExpirationForRechargeCard(_account_info *ptr, u_short valid_time, u_short faceValue) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; long expiration = 0,i_expiration = 0; u_short i_valid_time; /* incoming call */ int index, cos_id; COSTable *cosTableItem; PutLogFunID("UpdateExpirationForRechargeCard"); if(ptr->head>=MSISDN_HEAD_NUM || ptr->tail>=UNIT_STORE_ACCOUNT) { return; } if(OCS_with_external_CRM()) { shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = valid_time*24*60*60 + tvnow.tv_sec; shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = valid_time*24*60*60 + tvnow.tv_sec; return; } cos_id = shmp->prepaid_info[ptr->head][ptr->tail].cos_id; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; if(valid_time<=0) valid_time = 30; i_valid_time = valid_time; expiration = shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date; i_expiration = shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date; if((index=GetCardSystemParamByNearestValue(cos_id, faceValue))>=0){ valid_time = cosTableItem->rechargeCardValidity[index].moValidity; i_valid_time = cosTableItem->rechargeCardValidity[index].mtValidity; } if(cosTableItem->accountValidity[0].actionAfterRecharge) { if(expiration<(valid_time*24*3600+tvnow.tv_sec)) shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = valid_time*24*60*60 + tvnow.tv_sec; if(i_expiration<(i_valid_time*24*3600+tvnow.tv_sec)) shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = i_valid_time*24*60*60 + tvnow.tv_sec; } else { if(tvnow.tv_sec > expiration) shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = valid_time*24*60*60 + tvnow.tv_sec; else{ shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date += valid_time*24*60*60; } if(tvnow.tv_sec > i_expiration) shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = i_valid_time*24*60*60 + tvnow.tv_sec; else{ shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date += i_valid_time*24*60*60; } } if(cosTableItem->accountValidity[0].maxAccountValidityDays<=0) { cosTableItem->accountValidity[0].maxAccountValidityDays = 730; } if(shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date> tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) { shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; } if(shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date> tvnow.tv_sec +cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) { shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; } } void UpdateExpirationFirstCharge(_state_data *stashmp) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; u_short valid_time, /* outgoing call */ i_valid_time; /* incoming call */ int index,cos_id; u_short faceValue; _account_info *ptr; COSTable *cosTableItem; PutLogFunID("UpdateExpirationFirstCharge"); ptr = &stashmp->caller_info; if(ptr->head>=MSISDN_HEAD_NUM) { return; } cos_id = shmp->prepaid_info[ptr->head][ptr->tail].cos_id; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; valid_time = GetRechargeCardValidTime(stashmp); i_valid_time = valid_time; faceValue = GetRechargeCardFaceValue(stashmp); if((index=GetCardSystemParam(cos_id,faceValue))>=0){ valid_time = cosTableItem->rechargeCardValidity[index].moValidity; i_valid_time = cosTableItem->rechargeCardValidity[index].mtValidity; } shmp->prepaid_info[ptr->head][ptr->tail].mo_expiration_date = valid_time*24*60*60 + tvnow.tv_sec ; shmp->prepaid_info[ptr->head][ptr->tail].mt_expiration_date = i_valid_time*24*60*60 + tvnow.tv_sec ; } void UpdateExpirationFirstInquiry(_account_info *ptr, u_short valid_time) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; _prepaid_info *user_ptr = NULL; COSTable *cosTableItem; int cos_id= 0, bundle_plan_id=0; PutLogFunID("UpdateExpirationFirstInquiry"); if(ptr->head>=MSISDN_HEAD_NUM || ptr->tail>=UNIT_STORE_ACCOUNT) return; cos_id = ptr->cos_id%MaxCosTableItem; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; user_ptr = &shmp->prepaid_info[ptr->head][ptr->tail]; user_ptr->mo_expiration_date = valid_time*24*60*60 + tvnow.tv_sec ; user_ptr->mt_expiration_date = valid_time*24*60*60 + tvnow.tv_sec ; bundle_plan_id = cosTableItem->accountValidity[0].bundlePlanIDWhenActivated; if( bundle_plan_id > 0 && bundle_plan_id < MAX_BUNDLE_PLANS) { user_ptr->bundle_info.validity_date = user_ptr->mo_expiration_date; user_ptr->bundle_info.data = ppsParam.ppsTables.bundlePlans[bundle_plan_id].data * 1024 * 1024LL; user_ptr->bundle_info.mo_voice = ppsParam.ppsTables.bundlePlans[bundle_plan_id].mo_voice * 60; user_ptr->bundle_info.mt_voice = ppsParam.ppsTables.bundlePlans[bundle_plan_id].mt_voice * 60; user_ptr->bundle_info.sms = ppsParam.ppsTables.bundlePlans[bundle_plan_id].sms; } } void UpdateAccountExpiration(int head, int tail, u_short faceValue,u_short valid_time) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; u_long expiration=0,i_expiration=0; short index, i_valid_time; int cos_id; COSTable *cosTableItem; PutLogFunID("UpdateAccountExpiration"); if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { expiration = shmp->prepaid_info[head][tail].mo_expiration_date; i_expiration = shmp->prepaid_info[head][tail].mt_expiration_date; i_valid_time = valid_time; cos_id = shmp->prepaid_info[head][tail].cos_id; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; if((index=GetCardSystemParam(cos_id,faceValue))>=0){ valid_time = cosTableItem->rechargeCardValidity[index].moValidity; i_valid_time = cosTableItem->rechargeCardValidity[index].mtValidity; } if(cosTableItem->accountValidity[0].actionAfterRecharge) { if(expiration<(valid_time*24*3600+tvnow.tv_sec)) shmp->prepaid_info[head][tail].mo_expiration_date = valid_time*24*60*60 + tvnow.tv_sec; if(i_expiration<(i_valid_time*24*3600+tvnow.tv_sec)) shmp->prepaid_info[head][tail].mt_expiration_date = i_valid_time*24*60*60 + tvnow.tv_sec; } else { if(tvnow.tv_sec > expiration) shmp->prepaid_info[head][tail].mo_expiration_date = valid_time*24*60*60 + tvnow.tv_sec; else{ shmp->prepaid_info[head][tail].mo_expiration_date += valid_time*24*60*60; } if(tvnow.tv_sec > i_expiration) shmp->prepaid_info[head][tail].mt_expiration_date = i_valid_time*24*60*60 + tvnow.tv_sec; else{ shmp->prepaid_info[head][tail].mt_expiration_date += i_valid_time*24*60*60; } } if(cosTableItem->accountValidity[0].maxAccountValidityDays<=0) { cosTableItem->accountValidity[0].maxAccountValidityDays = 730; } if(shmp->prepaid_info[head][tail].mo_expiration_date> tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) { shmp->prepaid_info[head][tail].mo_expiration_date = tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; } if(shmp->prepaid_info[head][tail].mt_expiration_date> tvnow.tv_sec +cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600) { shmp->prepaid_info[head][tail].mt_expiration_date = tvnow.tv_sec + cosTableItem->accountValidity[0].maxAccountValidityDays*24*3600; } } } int UpdateAccountStatusFromNormalToSuspendedforExpiration(_prepaid_info *pUsrInfo, int head, int tail) { if(pUsrInfo == NULL) return 0; if(pUsrInfo->mo_expiration_date < tvnow.tv_sec) { if(pUsrInfo->status == T_NORMAL) { pUsrInfo->status = T_SUSPEND; SendAccountRealSync(head*UNIT_STORE_ACCOUNT+tail, 0.00, 0.00, OMC_OCODE_EDIT ); } } return 0; } int GetAccountStatus(_account_info *ptr) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetAccountStatus"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { if(shmp->prepaid_info[ptr->head][ptr->tail].balance>=ppsParam.serviceControl.maxBalance) shmp->prepaid_info[ptr->head][ptr->tail].status = T_SUSPEND; if(shmp->prepaid_info[ptr->head][ptr->tail].msisdn[MAX_MSISDN_BLEN-1]<=2) { shmp->prepaid_info[ptr->head][ptr->tail].status = T_FRESH; return T_EXTERNAL; } return shmp->prepaid_info[ptr->head][ptr->tail].status; } return T_EXTERNAL; } int GetAccountCosID(_account_info *ptr) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetAccountCosID"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { return shmp->prepaid_info[ptr->head][ptr->tail].cos_id; } return 0; } int GetSerivceNumberFlagPerCos(u8 cos_id, u8 service_type, u8 call_type); int GetServiceNumberFlag(_state_data *shmp, u8 service_pos) { int match_flag = 0; if(shmp->context_info.callType == CT_MO_CALL) { match_flag = GetSerivceNumberFlagPerCos(shmp->caller_info.cos_id, service_pos, 0); } else if(shmp->context_info.callType == CT_MO_SM ) { match_flag = GetSerivceNumberFlagPerCos(shmp->caller_info.cos_id, service_pos, 1); } else if(shmp->context_info.callType == CT_USSD) match_flag = GetSerivceNumberFlagPerCos(shmp->caller_info.cos_id, service_pos, 2); return match_flag; } int GetServiceType_0(_state_data *shmp) { int len0,len1; char buf[32]; char destination[32]; strcpy(destination, (char *)shmp->called_info.number); if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[HotLineNumberPosition].number)==0) { return SRV_CALL_HOTLINE; } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number)==0) { return SRV_INQUIRY; } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number)==0) { return SRV_SCRATCH_CARD_RECHARGE; //return SRV_RECHARGE_2TYPES; } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[CreditCardRechargeNumberPosition].number)==0) { return SRV_BUNDLE_PLAN; //SRV_CREDIT_CARD_RECHARGE; } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[ThirdPartyRechargeNumberPosition].number)==0) { return SRV_THIRD_PARTY_RECHARGE; } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[RechargeNumberPosition].number)==0) { return SRV_RECHARGE_2TYPES; //return SRV_SCRATCH_CARD_RECHARGE; } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[PalimRegisterNumberPosition].number) == 0) { shmp->process_info.palim_auto_register = 1; return SRV_SCRATCH_CARD_RECHARGE; } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[PoolAccountPosition].number)==0) { return SRV_POOL_ACCOUNT; } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[FeeTransferPosition].number)==0) { return SRV_FEE_TRANSFER; } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[FreeServicePosition].number)==0) { return SRV_FREE_SMS; } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[CallMeBackPosition].number)==0) { return SRV_CALL_ME_BACK; } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[TellMeNumber].number)==0) { return SRV_TELL_ME_NUMBER; } /* else if(IsCRDServiceNumber(destination)) { return SRV_CRD; } else if(IsPSTNMaitenance(destination)) { return SRV_OTHER_VMS_MAITENANCE; } else if(IsVMSDeposit(destination)) { return SRV_VMS_DEPOSIT; } */ else if(IsCallingCardNumber(destination)) {/*calling card */ return SRV_CALLINGCARD_MANAGE; } /* else if(IsDirectAccess(destination)) { return SRV_DIRECT_ACCESS; } else if(IsVMSReservedFunc(destination)) { return SRV_RESERVED_FUN; }*/ else { len0 = strlen((char *)ppsParam.ppsTables.serviceNumber[CallMeBackPosition].number); if(len0 !=0) { len1 = strlen(destination); if(len1>= 6 +len0) if(strncmp(destination, (char *)ppsParam.ppsTables.serviceNumber[CallMeBackPosition].number,len0)==0) { strcpy(buf,&destination[len0]); strcpy(destination,buf); destination[len1-len0] = 0; strcpy((char *)shmp->called_info.number, destination); shmp->process_info.all_in_one_input_flag = 1; return SRV_CALL_ME_BACK; } } len0 = strlen((char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); if(len0 !=0) { len1 = strlen(destination); if(len1>= 6 +len0) if(strncmp(destination, (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number, len0)==0) { strcpy(buf,&destination[len0]); strcpy(destination,buf); destination[len1-len0] = 0; strcpy((char *)shmp->called_info.number, destination); return SRV_RECHARGE_ONE_INPUT; } } len0 = strlen((char *)ppsParam.ppsTables.serviceNumber[PalimRegisterNumberPosition].number); if(len0 !=0) { len1 = strlen(destination); if(len1>= 6 +len0) if(strncmp(destination, (char *)ppsParam.ppsTables.serviceNumber[PalimRegisterNumberPosition].number,len0)==0) { strcpy(buf,&destination[len0]); strcpy(destination,buf); destination[len1-len0] = 0; strcpy((char *)shmp->called_info.number,destination); shmp->process_info.palim_auto_register = 1; return SRV_RECHARGE_ONE_INPUT; } } return SRV_NORMAL_MO_CALL; } return SRV_NORMAL_MO_CALL; } int GetServiceType(_state_data *shmp) { int len0,len1; char buf[32]; char destination[32]; strcpy(destination, (char *)shmp->called_info.number); shmp->process_info.tcos= NORMAL_RELEASE; if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[HotLineNumberPosition].number)==0) { if(GetServiceNumberFlag(shmp, HotLineNumberPosition)) return SRV_CALL_HOTLINE; else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number)==0) { if(GetServiceNumberFlag(shmp, InquiryNumberPosition)) return SRV_INQUIRY; else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number)==0) { if(GetServiceNumberFlag(shmp, ScratchCardRechargeNumberPosition)) return SRV_SCRATCH_CARD_RECHARGE; else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } //return SRV_RECHARGE_2TYPES; } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[CreditCardRechargeNumberPosition].number)==0) { if(GetServiceNumberFlag(shmp, CreditCardRechargeNumberPosition)) return SRV_CREDIT_CARD_RECHARGE; else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[ThirdPartyRechargeNumberPosition].number)==0) { if(GetServiceNumberFlag(shmp, ThirdPartyRechargeNumberPosition)) return SRV_THIRD_PARTY_RECHARGE; else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[RechargeNumberPosition].number)==0) { if(GetServiceNumberFlag(shmp, RechargeNumberPosition)) return SRV_RECHARGE_2TYPES; else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } //return SRV_SCRATCH_CARD_RECHARGE; } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[PalimRegisterNumberPosition].number) == 0) { if(GetServiceNumberFlag(shmp, PalimRegisterNumberPosition)) { shmp->process_info.palim_auto_register = 1; return SRV_SCRATCH_CARD_RECHARGE; } else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[PoolAccountPosition].number)==0) { if(GetServiceNumberFlag(shmp, PoolAccountPosition)) return SRV_POOL_ACCOUNT; else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[FeeTransferPosition].number)==0) { if(GetServiceNumberFlag(shmp, FeeTransferPosition)) return SRV_FEE_TRANSFER; else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[FreeServicePosition].number)==0) { if(GetServiceNumberFlag(shmp, FreeServicePosition)) return SRV_FREE_SMS; else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[CallMeBackPosition].number)==0) { if(GetServiceNumberFlag(shmp, CallMeBackPosition)) return SRV_CALL_ME_BACK; else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } } else if(strcmp(destination, (char *)ppsParam.ppsTables.serviceNumber[TellMeNumber].number)==0) { if(GetServiceNumberFlag(shmp, TellMeNumber)) return SRV_TELL_ME_NUMBER; else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } }/* else if(IsCRDServiceNumber(destination)) { return SRV_CRD; } else if(IsPSTNMaitenance(destination)) { return SRV_OTHER_VMS_MAITENANCE; } else if(IsVMSDeposit(destination)) { return SRV_VMS_DEPOSIT; } else if(IsOprNumber(destination)) { if(GetServiceNumberFlag(shmp, OPRNumberPosition)) return SRV_OPR_MANAGE; else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } }*/ else if(IsCallingCardNumber(destination)) {/*calling card */ if(GetServiceNumberFlag(shmp, VirtualCallingCardNumberPosition)) return SRV_CALLINGCARD_MANAGE; else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } } /* else if(IsDirectAccess(destination)) { return SRV_DIRECT_ACCESS; } else if(IsVMSReservedFunc(destination)) { return SRV_RESERVED_FUN; }*/ else { len0 = strlen((char *)ppsParam.ppsTables.serviceNumber[CallMeBackPosition].number); if(len0 !=0) { len1 = strlen(destination); if(len1>= 6 +len0) if(strncmp(destination, (char *)ppsParam.ppsTables.serviceNumber[CallMeBackPosition].number,len0)==0) { strcpy(buf,&destination[len0]); strcpy(destination,buf); destination[len1-len0] = 0; strcpy((char *)shmp->called_info.number,destination); if(GetServiceNumberFlag(shmp, CallMeBackPosition)) { shmp->process_info.all_in_one_input_flag = 1; return SRV_CALL_ME_BACK; } else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } } } len0 = strlen((char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); if(len0 !=0) { len1 = strlen(destination); if(len1>= 6 +len0) if(strncmp(destination, (char *)ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number,len0)==0) { strcpy(buf,&destination[len0]); strcpy(destination,buf); destination[len1-len0] = 0; strcpy((char *)shmp->called_info.number, destination); if(GetServiceNumberFlag(shmp, ScratchCardRechargeNumberPosition)) { return SRV_RECHARGE_ONE_INPUT; } else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } } } len0 = strlen((char *)ppsParam.ppsTables.serviceNumber[PalimRegisterNumberPosition].number); if(len0 !=0) { len1 = strlen(destination); if(len1>= 6 +len0) if(strncmp(destination, (char *)ppsParam.ppsTables.serviceNumber[PalimRegisterNumberPosition].number,len0)==0) { strcpy(buf,&destination[len0]); strcpy(destination,buf); destination[len1-len0] = 0; strcpy((char *)shmp->called_info.number,destination); if(GetServiceNumberFlag(shmp, PalimRegisterNumberPosition)) { shmp->process_info.palim_auto_register = 1; return SRV_RECHARGE_ONE_INPUT; } else { shmp->process_info.tcos= SRVICE_NOT_SUBSCRIBERED; shmp->process_info.voiceID = SERIVCE_NOT_APPLIED; } } } return SRV_NORMAL_MO_CALL; } return SRV_NORMAL_MO_CALL; } int GetUssdServiceType(_state_data *shmp) { int len0,len1; char buf[128]; char destination[128]; strcpy(destination, (char *)shmp->called_info.number); if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_HOTLINE].number)==0) { return SRV_CALL_HOTLINE; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_INQUIRY].number)==0) { return SRV_INQUIRY; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_RECHARGE].number)==0) { return SRV_SCRATCH_CARD_RECHARGE; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_FEE_TRANSFER].number)==0) { return SRV_FEE_TRANSFER; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_CALL_ME_BACK].number)==0) { return SRV_CALL_ME_BACK; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_TELL_ME_NUMBER].number)==0) { return SRV_TELL_ME_NUMBER; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_FRIEND_FAMILY_QUERY].number)==0) { return SRV_FAVORITE_NUMBER; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_BUNDLE_PLAN].number)==0) { return SRV_BUNDLE_PLAN; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_BUNDLE_QUERY].number)==0) { return SRV_BUNDLE_QUERY; } else { len0 = strlen((char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_CALL_ME_BACK].number); if(len0 !=0) { len1 = strlen(destination); if(len1>= 6 +len0) if(strncmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_CALL_ME_BACK].number,len0)==0) { strcpy(buf,&destination[len0]); strcpy(destination,buf); destination[len1-len0] = 0; strcpy((char *)shmp->called_info.number,destination); shmp->process_info.all_in_one_input_flag = 1; return SRV_CALL_ME_BACK; } } len0 = strlen((char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_RECHARGE].number); if(len0 !=0) { len1 = strlen(destination); if(len1>= 6 +len0) if(strncmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_RECHARGE].number,len0)==0) { strcpy(buf,&destination[len0]); strcpy(destination,buf); destination[len1-len0] = 0; strcpy((char *)shmp->called_info.number, destination); return SRV_RECHARGE_ONE_INPUT; } } } return SRV_NORMAL_MO_CALL; } int GetUssdServiceType_1(_state_data *shmp) { int len0,len1; char buf[32]; char destination[32]; strcpy(destination, (char *)shmp->called_info.number); if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_HOTLINE].number)==0) { if(GetServiceNumberFlag(shmp, HotLineNumberPosition)) return SRV_CALL_HOTLINE; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_INQUIRY].number)==0) { if(GetServiceNumberFlag(shmp, InquiryNumberPosition)) return SRV_INQUIRY; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_RECHARGE].number)==0) { if(GetServiceNumberFlag(shmp, ScratchCardRechargeNumberPosition)) return SRV_SCRATCH_CARD_RECHARGE; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_FEE_TRANSFER].number)==0) { if(GetServiceNumberFlag(shmp, FeeTransferPosition)) return SRV_FEE_TRANSFER; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_CALL_ME_BACK].number)==0) { if(GetServiceNumberFlag(shmp, CallMeBackPosition)) return SRV_CALL_ME_BACK; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_TELL_ME_NUMBER].number)==0) { if(GetServiceNumberFlag(shmp, TellMeNumber)) return SRV_TELL_ME_NUMBER; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_FRIEND_FAMILY_QUERY].number)==0) { if(GetServiceNumberFlag(shmp, FriendFamilyPosition)) return SRV_FAVORITE_NUMBER; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_BUNDLE_PLAN].number)==0) { return SRV_BUNDLE_PLAN; } else if(strcmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_BUNDLE_QUERY].number)==0) { return SRV_BUNDLE_QUERY; } else { len0 = strlen((char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_CALL_ME_BACK].number); if(len0 !=0) { len1 = strlen(destination); if(len1>= 6 +len0) if(strncmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_CALL_ME_BACK].number,len0)==0) { strcpy(buf,&destination[len0]); strcpy(destination,buf); destination[len1-len0] = 0; strcpy((char *)shmp->called_info.number,destination); if(GetServiceNumberFlag(shmp, CallMeBackPosition)) { shmp->process_info.all_in_one_input_flag = 1; return SRV_CALL_ME_BACK; } } } len0 = strlen((char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_RECHARGE].number); if(len0 !=0) { len1 = strlen(destination); if(len1>= 6 +len0) if(strncmp(destination, (char *)ppsParam.ppsTables.ussdServiceNumber[USSD_OC_RECHARGE].number,len0)==0) { strcpy(buf,&destination[len0]); strcpy(destination,buf); destination[len1-len0] = 0; strcpy((char *)shmp->called_info.number, destination); if(GetServiceNumberFlag(shmp, ScratchCardRechargeNumberPosition)) return SRV_RECHARGE_ONE_INPUT; } } } return SRV_NORMAL_MO_CALL; } int GetUssdServiceKey(u_char serviceKey) { int i; PutLogFunID("GetUssdServiceKey"); for(i=USSD_OC_HOTLINE;iprepaid_data; PutLogFunID("CheckWetherFavoriteNumber"); if(caller->head < MSISDN_HEAD_NUM && caller->tail prepaid_info[caller->head][caller->tail].favorite_numbers) return NOT_FAVORITE_NUMBER; cos_id = shmp->prepaid_info[caller->head][caller->tail].cos_id; serviceControlItem = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; if(serviceControlItem->balanceThresholdForFriendFamilyCall>GetAccountBalance(caller->head, caller->tail)) return NOT_FAVORITE_NUMBER; //if F*F PLAN, check total F&F call duraiton here for(i=0;iprepaid_info[caller->head][caller->tail].favorite_number[i][MAX_MSISDN_BLEN-1]; if(len>MAX_MSISDN_ALEN || len<2) continue; BcdToAscii(msisdn, shmp->prepaid_info[caller->head][caller->tail].favorite_number[i], MAX_MSISDN_ALEN); msisdn[len] = 0; CutUnknownPrefix(msisdn); //CheckWetherLocalNumber(msisdn); if(strcmp(msisdn,called_number)==0) return FAVORITE_NUMBER; } } return NOT_FAVORITE_NUMBER; } int GetAccountID(_account_info *ptr) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; _prepaid_info *user_info=NULL; PutLogFunID("GetAccountID"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { user_info = &shmp->prepaid_info[ptr->head][ptr->tail]; if(user_info->msisdn[MAX_MSISDN_BLEN-1]>=MIN_MSISDN_ALEN && user_info->msisdn[MAX_MSISDN_BLEN-1]<=MAX_MSISDN_ALEN) { return user_info->crm_info.account_id; } else return 0; } return 0; } int GetAccountCUG(_account_info *ptr) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; _prepaid_info *user_info=NULL; PutLogFunID("GetAccountCUG"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { user_info = &shmp->prepaid_info[ptr->head][ptr->tail]; if(user_info->msisdn[MAX_MSISDN_BLEN-1]>=MIN_MSISDN_ALEN && user_info->msisdn[MAX_MSISDN_BLEN-1]<=MAX_MSISDN_ALEN) { if(user_info->crm_info.vas_cug_state != 0)//cug service is blocked for rent charge failed return NOT_CUG_ACCOUNT; return user_info->cug_id; } else return NOT_CUG_ACCOUNT; } return NOT_CUG_ACCOUNT; } int GetDiscount(long timestamp,u_char discount_id) { int holiday_flag; _tariff_private *shmp; struct tm tm, *timep; int discount=0; int wday=0; PutLogFunID("GetDiscount"); shmp = blf_shmp; timep = (struct tm *) &tm; timep = (struct tm *) localtime( (time_t *)×tamp ); if(timep == NULL) { DebugMsg(debugmib.display.asciiOut, "Get Discount time error: %d", timestamp); return 100; } holiday_flag = shmp->holiday_flag[timep->tm_mon][timep->tm_mday-1];// advanced->Tariff plan->Holiday wday = (holiday_flag ? 7 : timep->tm_wday); #if DEBUG1 DebugMsg(debugmib.display.asciiOut, "Tm month: %d Tm mday: %d Holiday flag: %d", timep->tm_mon, timep->tm_mday, holiday_flag); #endif discount = shmp->bill_discount[discount_id][timep->tm_hour][wday];// advanced->Tariff plan->Discount #if DEBUG1 DebugMsg(debugmib.display.asciiOut, "Type: %d Hour: %d Week day: %d Discount: %d", id, timep->tm_hour, wday, discount); #endif if(discount < 0) discount = 0; return discount; } void set_truncation_flag(int flag) { ppsParam.serviceControl.truncation_flag = flag; } int get_truncation_flag() { return ppsParam.serviceControl.truncation_flag; } int SetTcpSyncFlag(int flag) { DebugMsg(debugmib.display.asciiOut,"Current tcp sync flag: %d", ppsParam.serviceControl.tcp_sync_flag); if(flag) ppsParam.serviceControl.tcp_sync_flag = 1; else ppsParam.serviceControl.tcp_sync_flag = 0; DebugMsg(debugmib.display.asciiOut,"New tcp sync flag: %d", ppsParam.serviceControl.tcp_sync_flag); return 1; } float ChargeGprsAccountBalance(_state_data *shmp,int real_duration) { int i=0,j; int discount=0; float charge=0; int itimes=0, unit_time=60; int duration, begin_time; _bill_tariff *ptar; PutLogFunID("ChargeAccountBalance"); begin_time = shmp->cdr_info.answertime, ptar = &shmp->process_info.tariff; duration = real_duration; duration -= ptar->free_time; if(duration<=0) return (charge = 0); if ((unit_time = ptar->unit_time) <= 0) unit_time = 60; itimes = (ceil)((double) duration / unit_time); discount = GetDiscount(begin_time,ptar->discountID); for (i=1; i<=itimes; i++) { if (i <= ptar->mini_unit ) { for(j=0;j < ptar->mini_unit;j++) { charge += BillingFormula(shmp,ptar,begin_time); begin_time += unit_time; } charge = (charge + ptar->adjustment); i = ptar->mini_unit; } else { charge = charge + BillingFormula(shmp,ptar,begin_time); begin_time += unit_time; } } charge = (charge * discount)/100; return charge; } int GetValidTime(_state_data *shmp,int begin_time, _bill_tariff *ptar, float balance, int init_bill, int overdraft) { int valid_time = 0; float charge=0, amount=0; int cos_id; COSTable *cosTableItem; PutLogFunID("GetValidTime"); cos_id = shmp->called_info.cos_id; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; if (init_bill == 0) valid_time = ptar->unit_time * ptar->mini_unit; else valid_time = ptar->unit_time; if (valid_time <= 0) valid_time = 60; charge = TimeToCharge(shmp,ptar, valid_time, begin_time,init_bill); amount = balance - charge + overdraft; #if DEBUG1 DebugMsg(debugmib.display.asciiOut, "GetValid time: balance: %.0f charge: %.0f draft: %d amount: %.0f", balance, charge, overdraft, amount); #endif /*How to get left seconds of account??? 2003-10-07 */ if(charge==0) { /* mo call */ if(shmp->context_info.callType != CT_MT_CALL) { //if(amount<=0) /* zero balance can't make free mo call */ if(amount<0) valid_time = 0; } else { if(cosTableItem->serviceControl[0].mtChargeFlag !=0 ) { // mt call, charged ,no balance if(cosTableItem->serviceControl[0].mtBalanceControl == 1) if(balance+overdraftserviceControl[0].mtBalanceThreshold) valid_time = 0; } else {// mt is free if(cosTableItem->serviceControl[0].mtChargeFlag == 1) { // mt balance threshold used if(balance+overdraftserviceControl[0].mtBalanceThreshold) valid_time = 0; } } } } else { if(amount<0) valid_time = 0; if(shmp->context_info.callType == CT_MT_CALL) if(cosTableItem->serviceControl[0].mtChargeFlag == 1) { if(balance+overdraftserviceControl[0].mtBalanceThreshold) valid_time = 0; } } /* if (amount < 0 && charge >= 0) valid_time = 0; */ return (valid_time*CYCLE_STATE_INTERVAL); } int GetMaxCallDuration(_state_data *shmp) { int /*init_flag=0 , */discount, maxDuration=0,free_time=0; float balance; _bill_tariff *ptar, tariff; //int j; //float charge; u32 calTime; int init_charge_cycle = 0; PutLogFunID("GetMaxCallDuration"); if(shmp->process_info.serviceType == SRV_CRD || (shmp->process_info.serviceType == SRV_NORMAL_MO_CALL && shmp->process_info.callConnected == 1 && !ppsParam.serviceControl.vms_allways_go)) { maxDuration = 12 * ONE_MINUTE_STATE_TIME ; shmp->process_info.maxCallDuration = maxDuration; return maxDuration; } ptar = &tariff; memcpy(ptar, &shmp->process_info.tariff, sizeof(_bill_tariff)); if(ptar->unit_time<=0) ptar->unit_time = 60; if(0) DebugMsg(debugmib.display.asciiOut, " %s:%d , tariff: %.2f+%.2f vs %.2f+%.2f", __FUNCTION__, __LINE__, shmp->process_info.tariff.tierRating.rating[0].base_fee, shmp->process_info.tariff.tierRating.rating[0].long_distance_fee, ptar->tierRating.rating[0].base_fee, ptar->tierRating.rating[0].long_distance_fee); if (shmp->process_info.ro_if.gy_ro_enable) { init_charge_cycle = ptar->free_time;// Ro: shmp->process_info.duration is in second. } else { init_charge_cycle = ptar->free_time*CYCLE_STATE_INTERVAL; } if(shmp->process_info.duration < init_charge_cycle) { free_time = ptar->free_time; maxDuration = free_time; //init_flag = 1; } else { /* init_charge_cycle = (ptar->free_time+ptar->mini_unit*ptar->unit_time)*CYCLE_STATE_INTERVAL; if(shmp->process_info.duration < init_charge_cycle) { init_flag = 1; } */ } discount = GetDiscount(tvnow.tv_sec, ptar->discountID); if(discount <= 0)// free call { maxDuration = MAX_CALL_DURATION; } else { if(shmp->context_info.callType == CT_MT_CALL) balance = (int)GetBalanceWithPromotionControl(shmp,&shmp->called_info) + GetOverdraft(&shmp->called_info); else balance = (int)GetBalanceWithPromotionControl(shmp,&shmp->caller_info) + GetOverdraft(&shmp->caller_info); if(balance<0) return 0; calTime = preLeftTime(shmp,balance,ptar); maxDuration += calTime; // free_time + pre left } shmp->process_info.maxCallDuration = maxDuration; return maxDuration; } void EncryptCardHRN(char *card_hrn,u_char *card_pwd) { char pinkey[32],tmp_hrn[32]; u_char u_buf[32]; int len; //PutLogFunID("EncryptCardHRN"); len = strlen(card_hrn); /* if(len == 10) // add for PNCC { StringCat(card_hrn,"00",12); memcpy(pinkey, card_hrn, 6); pinkey[6] = 0; StringCat(pinkey, "0", 8); EncryptPIN(card_pwd, card_hrn, PAN_KEY, pinkey); } else if(len == 11) // for Solomon, 2006-11-15 { StringCat(card_hrn,"0",12); memcpy(pinkey, card_hrn, 6); pinkey[6] = 0; StringCat(pinkey, "0", 8); EncryptPIN(card_pwd, card_hrn, PAN_KEY, pinkey); } */ if(len<10 || len>16) return; if(len<12) { strcpy(tmp_hrn,card_hrn); StringCat(tmp_hrn,"0",16); AsciiToBcd(u_buf,tmp_hrn,16); des(card_pwd,u_buf, (unsigned char *)PAN_KEY,0); } else if(len==12) { memcpy(pinkey, card_hrn, 6); pinkey[6] = 0; StringCat(pinkey, "0", 8); EncryptPIN(card_pwd, card_hrn, PAN_KEY, (unsigned char *)pinkey); } else if(len == 14) { memcpy(pinkey, card_hrn, 7); pinkey[7] = 0; StringCat(pinkey, "0", 8); EncryptPIN(card_pwd, card_hrn, PAN_KEY, (unsigned char *)pinkey); } else if(len==16) { AsciiToBcd(u_buf,card_hrn,16); des(card_pwd,u_buf, (unsigned char *)PAN_KEY,0); } else { if(0) DebugMsg(debugmib.display.asciiOut,"\33[31mPwd len:%d error!Must be 12,14,16 \33[0m",len); } #if DEBUG1 DebugMsg(debugmib.display.asciiOut, "card hrn: %s pinkey: %s", card_hrn, pinkey); #endif } u_char GetAccountZoneID(int head, int tail) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; int cos_id; COSTable *cosTableItem; PutLogFunID("GetAccountZoneID"); if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { cos_id = shmp->prepaid_info[head][tail].cos_id; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; return cosTableItem->tariff[0].moTariffID%MAX_ZONE_NUM; } return 0; } u_char GetAccountMTZoneID(int head, int tail) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; int cos_id; COSTable *cosTableItem; PutLogFunID("GetAccountMTZoneID"); if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { cos_id = shmp->prepaid_info[head][tail].cos_id; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; return cosTableItem->tariff[0].mtTariffID%MAX_ZONE_NUM; } return 0; } int GetAccountLastCallInfo(_account_info *ptr, _last_call_info *pInfo) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetAccountLastCallInfo"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { if(shmp->prepaid_info[ptr->head][ptr->tail].last_call_date>tvnow.tv_sec/2) { pInfo->last_call_type = shmp->prepaid_info[ptr->head][ptr->tail].last_call_type; pInfo->last_call_date = shmp->prepaid_info[ptr->head][ptr->tail].last_call_date; memcpy(pInfo->last_call_number, shmp->prepaid_info[ptr->head][ptr->tail].last_call_number, MAX_MSISDN_BLEN); return 1; } } return 0; } int IsSpanCall(_state_data *shmp) { PutLogFunID("IsSpanCall"); if (shmp->caller_info.location != GetAccountZoneID(shmp->caller_info.head, shmp->caller_info.tail) ) return TRUE; else return FALSE; } int IncreaseServiceSM(int head, int tail) { _prepaid_info *ptr; PutLogFunID("IncreaseServiceSM"); if(headprepaid_data.prepaid_info[head][tail]; if(ptr->free_sm_counter<0x7F) return (++ptr->free_sm_counter); return ptr->free_sm_counter; } return 0; } int IncreaseFavoriteNumberChangeCounterByOmc(_prepaid_info *ptr) { PutLogFunID("IncreaseFavoriteNumberChangeCounterByOmc"); if(ptr == NULL) return 0; if(ptr->fav_change_counter<0x7F) return (++ptr->fav_change_counter); return ptr->fav_change_counter; } int IncreaseFavoriteNumberChangeCounter(int head, int tail) { _prepaid_info *ptr; PutLogFunID("IncreaseFavoriteNumberChangeCounter"); if(headprepaid_data.prepaid_info[head][tail]; if(ptr->fav_change_counter<0x7F) return (++ptr->fav_change_counter); return ptr->fav_change_counter; } return 0; } int GetFriendFamilyChangeCounter(int head, int tail) { _prepaid_info *ptr; PutLogFunID("IncreaseFavoriteNumberChangeCounter"); if(headprepaid_data.prepaid_info[head][tail]; return ptr->fav_change_counter; } return 0; } int GetFriendFamilyCounter(int head, int tail) { _prepaid_info *ptr; PutLogFunID("IncreaseFavoriteNumberChangeCounter"); if(headprepaid_data.prepaid_info[head][tail]; return ptr->favorite_numbers; } return 0; } int GetAccountFriendFamilyPlanID(int head, int tail) { _prepaid_info *ptr; PutLogFunID("GetAccountFriendFamilyPlanID"); if(headprepaid_data.prepaid_info[head][tail]; return ptr->favorite_plan_id-1; } return -1; } int GetFavoriteNumberChangeCharge(_state_data *shmp) { int head,tail; int amount,tariff_id=0; //_prepaid_info *ptr; PutLogFunID("BillingFavoriteNumberChange"); 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].favEditChargeAmount; return amount; } int BillingFavoriteNumberChange(_state_data *shmp) { int head,tail; int amount,tariff_id=0; _prepaid_info *ptr; PutLogFunID("BillingFavoriteNumberChange"); 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].favEditChargeAmount; ptr->balance = ptr->balance - amount; shmp->caller_info.charge = amount; return amount; } int IsEnableToAddEditFavoriteNumber(_state_data *shmp, int flag) {/*flag = 0/1, add, edit */ CosFriendFamilyControl *friendFamilyControl; int cos_id,plan_id=0; cos_id = shmp->caller_info.cos_id; friendFamilyControl = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; plan_id = GetAccountFriendFamilyPlanID(shmp->caller_info.head,shmp->caller_info.tail); if(plan_id>MAX_FAVORITE_PALN) return 0; if(plan_id>=0 && flag == 0) { if(GetFriendFamilyCounter(shmp->caller_info.head,shmp->caller_info.tail)>= friendFamilyControl->friendFamilyPlan[plan_id].maxNumbers) return 0; } if(flag == 0) return 1; if(friendFamilyControl->friendFamilyChangeChargeFlag) { if(GetFriendFamilyChangeCounter(shmp->caller_info.head,shmp->caller_info.tail)<= friendFamilyControl->friendFamilyFreeChangeTimes) return 1; if(GetFavoriteNumberChangeCharge(shmp) > GetAccountBalance(shmp->caller_info.head,shmp->caller_info.tail)) { return 0; } } return 1; } int IsFavoriteNumberTypeOk(_state_data *shmp) { CosFriendFamilyControl *friendFamilyControl; int cos_id; char tmpChargeNumber[32]; cos_id = shmp->caller_info.cos_id; friendFamilyControl = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; strcpy(tmpChargeNumber,shmp->process_info.tmpDigits); CutUnknownPrefix(tmpChargeNumber); //tariff prefix always be E.164 if(!GetMOTariffData(shmp,&shmp->process_info.tariff, tmpChargeNumber, shmp->caller_info.location)) return 0; //no tariff switch(shmp->process_info.tariff.call_type) { case 0: //local if(friendFamilyControl->friendFamilyNumberTypeLocal) return 1; break; case 1: //NDD if(friendFamilyControl->friendFamilyNumberTypeNDD) return 1; break; case 2: //IDD if(friendFamilyControl->friendFamilyNumberTypeIDD) return 1; break; } return 0; } int CheckClearFriendFamilyNumber(int head, int tail, int rent_charge,int rent_id) { int cos_id; _prepaid_info *ptr; CosFriendFamilyControl *friendFamilyControl; PutLogFunID("CheckClearFriendFamilyNumber"); if(head>=MSISDN_HEAD_NUM || tail>=UNIT_STORE_ACCOUNT) { return 0; } ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; //if(ptr->fav_change_counter==0) // return 0; ptr->free_favorite_call = 0; ptr->free_favorite_sms = 0; cos_id = ptr->cos_id; friendFamilyControl = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; if(friendFamilyControl->keepOrRemoveFriendFamilyNumber==0) //remove { ptr->rent_type ^= (0x01<favorite_plan_id = 0; ptr->favorite_numbers = 0; ptr->favorite_plan_state = 0; ptr->fav_change_counter = 0; memset(ptr->favorite_number,0x00,MAX_FAVORITE_NUMBERS*MAX_MSISDN_BLEN); if(ppsParam.ppsTables.cosTable[cos_id].smsNotificationInquiry[0].smsNotificationWhenFriendFamilyServiceRemoved ) sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_REMOVE); return 1; } if(friendFamilyControl->balanceThresholdToKeepFriendFamilyNumber!=0 && friendFamilyControl->balanceThresholdToKeepFriendFamilyNumber>GetAccountBalance( head, tail)) { ptr->favorite_plan_state = 1; if(ppsParam.ppsTables.cosTable[cos_id].smsNotificationInquiry[0].smsNotificationWhenFriendFamilyServiceSuspend) sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_SERVICE_SUSPEND); return 1; } if(rent_charge>GetAccountBalance( head, tail)) { ptr->favorite_plan_state = 1; if(ppsParam.ppsTables.cosTable[cos_id].smsNotificationInquiry[0].smsNotificationWhenFriendFamilyServiceSuspend) sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_SERVICE_SUSPEND); return 1; } return 0; } int CheckFriendFamilyPlanFreeCallOrSMS(int head, int tail, int type, int duration) /* type0=call, 1=sms */ { /* when type0=call, check if call duration + existing free call duration exceeds threshold */ int cos_id, plan_id=0; _prepaid_info *ptr; CosFriendFamilyControl *friendFamilyControl; PutLogFunID("CheckFriendFamilyPlanFreeSMS"); if(head>=MSISDN_HEAD_NUM || tail>=UNIT_STORE_ACCOUNT) { return 0; } ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; if(ptr->favorite_numbers ==0) return 0; if(ptr->favorite_plan_id<=0 || ptr->favorite_plan_id>MAX_FAVORITE_PALN || ptr->favorite_plan_state !=0) return 0; plan_id = ptr->favorite_plan_id-1; cos_id = ptr->cos_id; friendFamilyControl = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; switch(type) { case 0: if(friendFamilyControl->friendFamilyPlan[plan_id].freeCallDuration == 0) return 1; if((ptr->free_favorite_call+duration) >= friendFamilyControl->friendFamilyPlan[plan_id].freeCallDuration*60) //keep return 0; break; case 1: default: if(friendFamilyControl->friendFamilyPlan[plan_id].freeSMS == 0) return 1; if(ptr->free_favorite_sms >= friendFamilyControl->friendFamilyPlan[plan_id].freeSMS) //keep return 0; break; } return 1; } int IncreaseFriendFamilyFreeCallDuration(int head, int tail, int duration) { _prepaid_info *ptr; PutLogFunID("IncreaseFriendFamilyFreeCallDuration"); if(head>=MSISDN_HEAD_NUM || tail>=UNIT_STORE_ACCOUNT) { return 0; } ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; if(1) { int cos_id, max_free_duration, plan_id; cos_id = ptr->cos_id; plan_id = ptr->favorite_plan_id - 1; if(plan_id>0 && plan_id0) if((ptr->free_favorite_call + duration/CYCLE_STATE_INTERVAL)>max_free_duration) { sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_PLAN_EXHAUST); } } } ptr->free_favorite_call += ceil( (double) duration / CYCLE_STATE_INTERVAL); return 1; } int IncreaseFriendFamilyFreeSMSCounter(int head, int tail) { _prepaid_info *ptr; PutLogFunID("IncreaseFriendFamilyFreeSMSCounter"); if(head>=MSISDN_HEAD_NUM || tail>=UNIT_STORE_ACCOUNT) { return 0; } ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; if(1) { int cos_id, max_free_sms, plan_id; cos_id = ptr->cos_id; plan_id = ptr->favorite_plan_id - 1; if(plan_id>0 && plan_id0) if((ptr->free_favorite_sms +1 )>max_free_sms) { sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_PLAN_EXHAUST); } } } ptr->free_favorite_sms++; return 1; } float GetSMSTariff(_state_data *shmp,u_char tariff_id) { int i,flag=0,len=0,maxlen=0,index=0; float sms_fee = 0; int discount=100; _bill_sms *ptr; char bill_no[64]; //tariff_id = shmp->caller_info.location; //GetAccountZoneID(shmp->caller_info.head,shmp->caller_info.tail); if(tariff_id>=MAX_ZONE_NUM ) tariff_id = 0; if(shmp->process_info.mnp_status ) sprintf(bill_no,"%s%s",shmp->process_info.routing_number, shmp->called_info.number); else strcpy(bill_no, (char *)shmp->charge_info.number); for(i=1;ibill_sms[tariff_id][i]; if(ptr->id !=0) { len = strlen(ptr->bill_id); if(!strncasecmp(bill_no,ptr->bill_id,len)) if(len>maxlen) { maxlen = len; flag = 1; index = i; } } } if(flag == 0) { if(shmp->process_info.mnp_status ) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\33[33m SMS to ported number, but no RN+MSISDN(%s) billing prefix\33[0m", bill_no); DebugMsg(debugmib.display.asciiOut, "\33[33m Use dialing prefix %s as billing prefix\33[0m", shmp->charge_info.number); } strcpy(bill_no, (char *)shmp->charge_info.number); for(i=1;ibill_sms[tariff_id][i]; if(ptr->id !=0) { len = strlen(ptr->bill_id); if(!strncasecmp(bill_no,ptr->bill_id,len)) if(len>maxlen) { maxlen = len; flag = 1; index = i; } } } } if(flag == 0) ptr = &blf_shmp->bill_sms[tariff_id][DEFAULT_SMS_BILLING]; else ptr = &blf_shmp->bill_sms[tariff_id][index]; } else { ptr = &blf_shmp->bill_sms[tariff_id][index]; } memcpy(&shmp->process_info.smsTariff,ptr,sizeof(_bill_sms)); sms_fee = ptr->base_fee; discount = GetDiscount(tvnow.tv_sec,ptr->discountID); // DebugMsg(debugmib.display.asciiOut, // "sms tariff : fee:%0.4f discountID:%d discount: %d ", // sms_fee,ptr->discountID,discount); sms_fee = sms_fee * discount /100; // if(!shmp->process_info.cap_flag) shmp->process_info.cap_flag = ptr->cap_flag; if(shmp->process_info.favoriteCall) { //COSTable *cosTableItem; //cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; if(CheckFriendFamilyPlanFreeCallOrSMS(shmp->caller_info.head, shmp->caller_info.tail, 1,0)) { sms_fee = 0; /* free friend family SMS */ shmp->process_info.cap_flag = 0; shmp->process_info.favoriteCall = FRIEND_FAMILY_FREE_SMS; /* free friend family call */ } } return sms_fee; } static void CheckCAPSMSNotification(_state_data *staPtr, _account_info *accountPtr, u_char cos_id, int cap_type, float charge, int amount ) /* cap_type: 0=call, 1=sms */ { int cap_plan,cap_seg, type,notifyFlag=0; float c_threshold=0; _prepaid_info *subPtr=NULL; COSTable *cosTableItem; CosCapPlan *capPlanPtr; PutLogFunID("CheckCAPSMSNotification"); if(staPtr->process_info.cap_notify_flag) /* already send notification SM in this call */ return; cap_plan = staPtr->process_info.cap_plan; cap_seg = staPtr->process_info.cap_seg; type = staPtr->process_info.cap_flag; if(cap_seg>=3) return; /* reach the last CAP segment */ subPtr = &ramshm_ptr->prepaid_data.prepaid_info[accountPtr->head][accountPtr->tail]; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; capPlanPtr = &cosTableItem->capPlan[cap_plan]; if(cap_seg == 0) c_threshold = (float)capPlanPtr->threshold0; else if(cap_seg == 1) c_threshold = (float)capPlanPtr->threshold1; else if(cap_seg == 2) c_threshold = (float)capPlanPtr->threshold2; switch(cap_type) { case 0: if(capPlanPtr->type == 0) //counter { if(type == 1) /* in net call */ { if((subPtr->in_net_cap_call_duration + amount)>=c_threshold) notifyFlag = 1; } else if(type == 2) /* out net call */ { if((subPtr->out_net_cap_call_duration + amount)>=c_threshold) notifyFlag = 1; } } else if(charge>0) //balance { if(type == 1) { if((subPtr->in_net_cap_call_balance + charge)>=c_threshold) notifyFlag = 1; } else if(type == 2) { if((subPtr->out_net_cap_call_balance + charge)>=c_threshold) notifyFlag = 1; } } break; case 1: if(capPlanPtr->type == 0) //counter { if(type == 1) { if((subPtr->in_net_cap_sms_counter + 1)==c_threshold) notifyFlag = 1; } else if(type == 2) { if((subPtr->out_net_cap_sms_counter + 1)==c_threshold) notifyFlag = 1; } } else if(charge>0) //balance { if(type == 1) { if((subPtr->in_net_cap_sms_balance + charge)>=c_threshold) notifyFlag = 1; } else if(type == 2) { if((subPtr->out_net_cap_sms_balance + charge)>=c_threshold) notifyFlag = 1; } } break; } if(notifyFlag) { if(cap_seg == 0) PPSSendUserSMSNotification(accountPtr->head, accountPtr->tail, (char *)getSmsSentenceNative(0,SMS_CAPSMS_NOTIFY)); else if(cap_seg == 1) PPSSendUserSMSNotification(accountPtr->head, accountPtr->tail, (char *)getSmsSentenceNative(0,SMS_CAPSMS_1_NOTIFY)); else {PPSSendUserSMSNotification(accountPtr->head, accountPtr->tail, (char *)getSmsSentenceNative(0,SMS_CAPSMS_2_NOTIFY));} staPtr->process_info.cap_notify_flag = 1; } } void UpdateSubsCapInfo(_account_info *ptr, int cap_type,float charge, int amount, _state_data *sta_ptr) { /* cap type: 0=call, 1=sm */ _prepaid_data *shmp=&ramshm_ptr->prepaid_data; _prepaid_info *subPtr; u_char cos_id; int type=sta_ptr->process_info.cap_flag; COSTable *cosTableItem; PutLogFunID("UpdateSubsCapBalance"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { subPtr = &shmp->prepaid_info[ptr->head][ptr->tail]; cos_id = subPtr->cos_id%MaxCosTableItem; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenCapPlanChanged) { CheckCAPSMSNotification(sta_ptr,ptr,cos_id,cap_type,charge, amount); } if(cap_type==0) { if(type == 1) { subPtr->in_net_cap_call_balance = subPtr->in_net_cap_call_balance + charge; subPtr->in_net_cap_call_duration += amount; subPtr->in_net_cap_balance = subPtr->in_net_cap_balance + charge; } else if(type == 2) { subPtr->out_net_cap_call_balance = subPtr->out_net_cap_call_balance + charge; subPtr->out_net_cap_call_duration += amount; subPtr->out_net_cap_balance = subPtr->out_net_cap_balance + charge; } } else { if(type == 1) { subPtr->in_net_cap_sms_balance = subPtr->in_net_cap_sms_balance + charge; subPtr->in_net_cap_sms_counter ++; subPtr->in_net_cap_balance = subPtr->in_net_cap_balance + charge; } else if(type == 2) { subPtr->out_net_cap_sms_balance = subPtr->out_net_cap_sms_balance + charge; subPtr->out_net_cap_sms_counter ++; subPtr->out_net_cap_balance = subPtr->out_net_cap_balance + charge; } } } } void GetSubsCapInfo(_account_info *ptr,int cap_type, float *balance, int *counter, int type, int cap_flag) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetSubsCapInfo"); if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { if(cap_flag == CAP_TYPE_BOTH) { if(type == 0) { *balance = shmp->prepaid_info[ptr->head][ptr->tail].in_net_cap_balance; *counter = 0; } else { *balance = shmp->prepaid_info[ptr->head][ptr->tail].out_net_cap_balance; *counter = 0; } return; } if(cap_type==0) { if(type==0) /* int net */ { *balance = shmp->prepaid_info[ptr->head][ptr->tail].in_net_cap_call_balance; *counter = shmp->prepaid_info[ptr->head][ptr->tail].in_net_cap_call_duration; } else /* out net */ { *balance = shmp->prepaid_info[ptr->head][ptr->tail].out_net_cap_call_balance; *counter = shmp->prepaid_info[ptr->head][ptr->tail].out_net_cap_call_duration; } } else { if(type==0) /* int net */ { *balance = shmp->prepaid_info[ptr->head][ptr->tail].in_net_cap_sms_balance; *counter = shmp->prepaid_info[ptr->head][ptr->tail].in_net_cap_sms_counter; } else /* out net */ { *balance = shmp->prepaid_info[ptr->head][ptr->tail].out_net_cap_sms_balance; *counter = shmp->prepaid_info[ptr->head][ptr->tail].out_net_cap_sms_counter; } } } else { *balance = 0; *counter = 0; } } int GetSubsCapTariffID(_state_data *shmp, int call_type) { int cos_id=0,tariff_id=-1,cap_plan=0,loop=0; float cap_balance; int cap_counter; float c_threshold0=0,c_threshold1=0,c_threshold2=0; int cap_flag,cap_type; COSTable *cosTableItem; CosCapPlan *capPlanPtr; PutLogFunID("GetSubsCapTariffID"); cos_id = shmp->caller_info.cos_id%MaxCosTableItem; if(call_type == 0) /* call */ { cap_type = 1; /* call */ cap_flag = 1; } else /* sm , please refer param.h cap_plan for the assignment*/ { cap_type = 2; cap_flag = 2; } cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; for(loop=0;loopcapPlan[loop].flag & cap_flag )== cap_type && //call shmp->process_info.cap_flag == (loop%2+1) ) { cap_flag = cosTableItem->capPlan[loop].flag; /* 0=disable, 1/2/3=cap by SM/CALL/BOTH */ cap_plan = loop; break; } } shmp->process_info.cap_plan = cap_plan; GetSubsCapInfo(&shmp->caller_info, call_type, // call=0 or sm=1 &cap_balance, &cap_counter, shmp->process_info.cap_flag-1, //innet=0, outnet=1 cap_flag ); capPlanPtr = &cosTableItem->capPlan[cap_plan]; c_threshold0 = (float)capPlanPtr->threshold0; c_threshold1 = (float)capPlanPtr->threshold1; c_threshold2 = (float)capPlanPtr->threshold2; if(capPlanPtr->type == 0) { if(c_threshold0>0) { if(cap_countertariffID0; shmp->process_info.cap_seg = 0; } else if(c_threshold1>0) { if(cap_countertariffID1; shmp->process_info.cap_seg = 1; } else if(c_threshold2>0) { if(cap_countertariffID2; shmp->process_info.cap_seg = 2; } else { tariff_id = capPlanPtr->tariffID3; shmp->process_info.cap_seg = 3; } } else { tariff_id = capPlanPtr->tariffID2; shmp->process_info.cap_seg = 2; } } else { tariff_id = capPlanPtr->tariffID1; shmp->process_info.cap_seg = 1; } } } else { if(c_threshold0>0) { if(cap_balancetariffID0; shmp->process_info.cap_seg = 0; } else if(c_threshold1>0) { if(cap_balancetariffID1; shmp->process_info.cap_seg = 1; } else if(c_threshold2>0) { if(cap_balancetariffID2; shmp->process_info.cap_seg = 2; } else { tariff_id = capPlanPtr->tariffID3; shmp->process_info.cap_seg = 3; } } else { tariff_id = capPlanPtr->tariffID2; shmp->process_info.cap_seg = 2; } } else { tariff_id = capPlanPtr->tariffID1; shmp->process_info.cap_seg = 1; } } } return tariff_id; } int UpdateAccountBundlePlanInfoWarningFlag(_state_data *shmp, int flag) { _prepaid_data *ptr =&ramshm_ptr->prepaid_data; _prepaid_info *sub_ptr = NULL; int head, tail; PutLogFunID("UpdateAccountBundlePlanInfoWarningFlag"); head = shmp->caller_info.head; tail = shmp->caller_info.tail; if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { sub_ptr = &ptr->prepaid_info[head][tail]; sub_ptr->bundle_info.warning_sms_flag = flag; } return 1; } int UpdateAccountBundlePlanInfo(_account_info *shmp, long set_value[7]) { _prepaid_data *ptr =&ramshm_ptr->prepaid_data; _prepaid_info *sub_ptr = NULL; int head, tail; PutLogFunID("UpdateAccountBundlePlanInfo"); head = shmp->head; tail = shmp->tail; if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { sub_ptr = &ptr->prepaid_info[head][tail]; if(sub_ptr->bundle_info.data == 0)// set voice/sms to 0, if data==0 when subscribe bundle { sub_ptr->bundle_info.validity_date = tvnow.tv_sec - 1000; sub_ptr->bundle_info.mo_voice = 0; sub_ptr->bundle_info.mt_voice = 0; sub_ptr->bundle_info.sms = 0; } //sub_ptr->balance = sub_ptr->balance + set_value[0]; sub_ptr->bundle_info.data += ( set_value[1] * 1024 * 1024); sub_ptr->bundle_info.mo_voice += ( set_value[2] * 60 ); sub_ptr->bundle_info.mt_voice += ( set_value[3] * 60 ); sub_ptr->bundle_info.sms += set_value[4]; sub_ptr->bundle_info.warning_sms_flag = set_value[6]; if(sub_ptr->bundle_info.validity_date < tvnow.tv_sec) { sub_ptr->bundle_info.validity_date = tvnow.tv_sec + set_value[5] * 24 * 3600; } else { sub_ptr->bundle_info.validity_date += set_value[5] * 24 * 3600; } } return 1; } int GetAccountBundlePlanInfo(_account_info *ptr, long ret_value[6]) { _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; _prepaid_info *sub_ptr = NULL; int head, tail; int retval = 0; int bundle_info_updated_flag = 1; PutLogFunID("GetAccountBundlePlanInfo"); head = ptr->head; tail = ptr->tail; if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { sub_ptr = &data_ptr->prepaid_info[head][tail]; // see if we have to set bundle to 0=================================== if ((sub_ptr->bundle_info.validity_date > 0) && (sub_ptr->bundle_info.validity_date < tvnow.tv_sec))// 1) set bundle to 0, if expired when querying. { memset(&sub_ptr->bundle_info, 0x00, sizeof(_bundle_info)); } else if (((sub_ptr->bundle_info.validity_date >= tvnow.tv_sec) && (sub_ptr->bundle_info.data <= 0))\ || ((sub_ptr->bundle_info.validity_date == 0) && (sub_ptr->bundle_info.data > 0)))// 2) set bundle to 0, if data == 0 and not expired // && sub_ptr->bundle_info.mo_voice == 0 // && sub_ptr->bundle_info.mt_voice == 0 // && sub_ptr->bundle_info.sms == 0) { memset(&sub_ptr->bundle_info, 0x00, sizeof(_bundle_info)); } else { bundle_info_updated_flag = 0;// no change, so do not have to sync. } //===================================================== // return bundle when data > 0 and not expired. if ((sub_ptr->bundle_info.data > 0) && (sub_ptr->bundle_info.validity_date >= tvnow.tv_sec)) { retval = 1; } // ret_value[0] = (sub_ptr->bundle_info.data /( 1024*1024)); ret_value[1] = (sub_ptr->bundle_info.mo_voice / 60 ); ret_value[2] = (sub_ptr->bundle_info.mt_voice / 60 ); ret_value[3] = ( sub_ptr->bundle_info.sms ); ret_value[4] = sub_ptr->bundle_info.validity_date; ret_value[5] = sub_ptr->bundle_info.warning_sms_flag; } if(bundle_info_updated_flag ) { SendAccountRealSync_2(ptr,0.0,0.0,OMC_OCODE_EDIT); } return retval; } extern void pps_print_event(u_char logMsisdnFlag,const char *fmt, ...); long long pps_get_account_bundle_data(_state_data *shmp)// get remained Bytes from user bundle info { _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; _prepaid_info *sub_ptr = NULL; int head, tail; PutLogFunID("pps_get_account_bundle_data"); head = shmp->caller_info.head; tail = shmp->caller_info.tail; if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { sub_ptr = &data_ptr->prepaid_info[head][tail]; /* pps_print_event(shmp->process_info.logMsisdn,"[%04d] %s, bundle data=%lld, validity=%ld, now time=%ld", shmp->process_info.portid, __FUNCTION__, sub_ptr->bundle_info.data, sub_ptr->bundle_info.validity_date, tvnow.tv_sec); */ if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) { return sub_ptr->bundle_info.data; } else { return 0; } } return 0; } int pps_get_account_bundle_mo_voice(_state_data *shmp)// get remained Bytes from user bundle info { _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; _prepaid_info *sub_ptr = NULL; int head, tail; PutLogFunID("pps_get_account_bundle_mo_voice"); head = shmp->caller_info.head; tail = shmp->caller_info.tail; if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { sub_ptr = &data_ptr->prepaid_info[head][tail]; if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) { return sub_ptr->bundle_info.mo_voice; } else { return 0; } } return 0; } int pps_update_account_bundle_mo_voice(_state_data *shmp, int seconds)// { _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; _prepaid_info *sub_ptr = NULL; int head, tail; PutLogFunID("pps_update_account_bundle_mo_voice"); head = shmp->caller_info.head; tail = shmp->caller_info.tail; if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { sub_ptr = &data_ptr->prepaid_info[head][tail]; if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) { sub_ptr->bundle_info.mo_voice += seconds; if(sub_ptr->bundle_info.mo_voice <= 0) { sub_ptr->bundle_info.mo_voice = 0; subscribe_bundle_plan_send_used_up_info((char *)shmp->caller_info.number, SMS_BUNDLE_PLAN_VOICE_USEDUP); /* should only send MO voice is used up */ } } else { return 0; } } return 1; } int pps_get_account_bundle_mt_voice(_state_data *shmp)// { _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; _prepaid_info *sub_ptr = NULL; int head, tail; PutLogFunID("pps_get_account_bundle_mt_voice"); head = shmp->called_info.head; tail = shmp->called_info.tail; if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { sub_ptr = &data_ptr->prepaid_info[head][tail]; if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) { return sub_ptr->bundle_info.mo_voice;// mt use the same bundle as mo } else { return 0; } } return 0; } int pps_update_account_bundle_mt_voice(_state_data *shmp, int seconds)// { _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; _prepaid_info *sub_ptr = NULL; int head, tail; PutLogFunID("pps_update_account_bundle_mt_voice"); head = shmp->called_info.head; tail = shmp->called_info.tail; if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { sub_ptr = &data_ptr->prepaid_info[head][tail]; if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) { sub_ptr->bundle_info.mo_voice += seconds;// mt use the same bundle as mo if(sub_ptr->bundle_info.mo_voice <= 0) { sub_ptr->bundle_info.mo_voice = 0; subscribe_bundle_plan_send_used_up_info((char *)shmp->called_info.number, SMS_BUNDLE_PLAN_VOICE_USEDUP); /* should only send MT voice is used up */ } } else { return 0; } } return 1; } int pps_get_account_bundle_mo_sms(_state_data *shmp)// get remained Bytes from user bundle info { _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; _prepaid_info *sub_ptr = NULL; int head, tail; PutLogFunID("pps_get_account_bundle_mo_sms"); head = shmp->caller_info.head; tail = shmp->caller_info.tail; if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { sub_ptr = &data_ptr->prepaid_info[head][tail]; if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) { return sub_ptr->bundle_info.sms; } else { return 0; } } return 0; } int pps_update_account_bundle_mo_sms(_state_data *shmp, int count)// get remained Bytes from user bundle info { _prepaid_data *data_ptr =&ramshm_ptr->prepaid_data; _prepaid_info *sub_ptr = NULL; int head, tail; PutLogFunID("pps_get_account_bundle_mo_voice"); head = shmp->caller_info.head; tail = shmp->caller_info.tail; if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { sub_ptr = &data_ptr->prepaid_info[head][tail]; // if(sub_ptr->bundle_info.validity_date > tvnow.tv_sec) { sub_ptr->bundle_info.sms += count; if(sub_ptr->bundle_info.sms <= 0) { sub_ptr->bundle_info.sms = 0; subscribe_bundle_plan_send_used_up_info((char *)shmp->caller_info.number, SMS_BUNDLE_PLAN_SMS_USEDUP); /* should only send MO SMS is used up */ } } /* else { return 0; } */ } return 1; } extern int ocs_get_charge_prefix(char *dialed_number, char *prefix, char *area_name, int *call_type); extern int crm_check_if_cug_call(_account_info *caller, _account_info *called); int BillingSMSProc(_state_data *shmp, int sms_num) { float balance = 0, discount=100.0; float mosms_unit_charge ; int cos_id,tariff_id; COSTable *cosTableItem = NULL; int charge_num = sms_num, bundle_used_num = 0; CosServiceControl *serviceControlItem = NULL; PutLogFunID("BillingSMSProc"); if(OCS_with_external_CRM()) { if(crm_check_if_cug_call(&shmp->caller_info, &shmp->called_info)) { mosms_unit_charge = 0; shmp->process_info.rest_if.total_plan_value = 0; shmp->process_info.rest_if.used_plan_value = 0; } else mosms_unit_charge = shmp->process_info.rest_if.unit_charge * shmp->process_info.rest_if.tariff_discount / discount; } else mosms_unit_charge = GetSMSTariff(shmp,shmp->caller_info.location); // Check Cap or Bundle is used================================ cos_id = shmp->caller_info.cos_id; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; serviceControlItem = &cosTableItem->serviceControl[0]; if(serviceControlItem->cap_or_bundle_in_tariff)// bundle is used, so we can set bundle flag and clear cap flag { shmp->process_info.bundle_flag = shmp->process_info.cap_flag; shmp->process_info.cap_flag = 0; } //================================================== if(shmp->process_info.bundle_flag) { int left_mo_sms = 0; left_mo_sms = pps_get_account_bundle_mo_sms(shmp); if(left_mo_sms > 0) { if (left_mo_sms >= charge_num) { shmp->caller_info.fee = 0; shmp->caller_info.valid_time = 10*ONE_MINUTE_STATE_TIME; shmp->called_info.fee = 0; shmp->called_info.valid_time = shmp->caller_info.valid_time; bundle_used_num = charge_num; return bundle_used_num;// bundle charge num } else { charge_num -= left_mo_sms; bundle_used_num = left_mo_sms; } } else { shmp->process_info.bundle_flag = 0; } } if(shmp->process_info.cap_flag) { tariff_id=GetSubsCapTariffID(shmp,CAP_SMS); if(tariff_id>=0) { mosms_unit_charge = GetSMSTariff(shmp,tariff_id); /* there should always be DEFAULT tariff prefix */ shmp->caller_info.location = tariff_id; } } //no roaming fee charged for ROAMING SMS, 2005-05-09 switch(shmp->process_info.call_type) { case CT_MO_SM: if(shmp->process_info.serviceType == SRV_SCRATCH_CARD_RECHARGE || shmp->process_info.serviceType == SRV_RECHARGE_2TYPES || shmp->process_info.serviceType == SRV_FEE_TRANSFER || shmp->process_info.serviceType == SRV_FREE_SMS || shmp->process_info.serviceType == SRV_CALL_ME_BACK || shmp->process_info.serviceType == SRV_BUNDLE_PLAN || shmp->process_info.serviceType == USSD_OC_BUNDLE_QUERY) { shmp->process_info.cap_flag = 0; shmp->caller_info.fee = 0; shmp->caller_info.valid_time = 10*ONE_MINUTE_STATE_TIME; shmp->called_info.fee = 0; shmp->called_info.valid_time = shmp->caller_info.valid_time; return bundle_used_num; } if(cosTableItem->serviceControl[0].moThresholdSet) { balance = (int)GetBalanceWithPromotionControl(shmp,&shmp->caller_info) + GetOverdraft(&shmp->caller_info) - (cosTableItem->serviceControl[0].moMinimumBalance); if(balance<0) { shmp->caller_info.fee = 0; shmp->caller_info.valid_time = 0; shmp->called_info.fee = 0; shmp->called_info.valid_time = 0; return bundle_used_num; } } balance = GetBalanceWithPromotionControl(shmp,&shmp->caller_info) + GetOverdraft(&shmp->caller_info); if(shmp->process_info.serviceType == SRV_INQUIRY ) { shmp->process_info.cap_flag = 0; if(!(cosTableItem->smsNotificationInquiry[0].chargeWhenInquiryBySMS)) { /* not charging on SM inquring */ shmp->caller_info.fee = 0; shmp->caller_info.valid_time = 10*ONE_MINUTE_STATE_TIME; /* should be a parameter */ shmp->called_info.fee = 0; shmp->called_info.valid_time = shmp->caller_info.valid_time; return bundle_used_num; } else { /* inquiry charged, recharge should be always free,not yet,2004-01-06 */ if(IncreaseServiceSM(shmp->caller_info.head, shmp->caller_info.tail)<= (cosTableItem->smsNotificationInquiry[0].freeInquiryPerDay)) { shmp->caller_info.fee = 0; shmp->caller_info.valid_time = 10*ONE_MINUTE_STATE_TIME; shmp->called_info.fee = 0; shmp->called_info.valid_time = shmp->caller_info.valid_time; return bundle_used_num; } } } /* zero balance can't send free sms,06-02-27 */ /* if(balance == 0 && mosms_unit_charge==0) { shmp->caller_info.valid_time = 0; // should be a parameter shmp->called_info.valid_time = 0; shmp->process_info.tcos = CALLER_CREDIT_OUT; // no enough balance } else if(balance>=mosms_unit_charge) */ if(balance>=(mosms_unit_charge * charge_num)) { shmp->caller_info.valid_time = 10*ONE_MINUTE_STATE_TIME; /* should be a parameter */ shmp->called_info.valid_time = 10*ONE_MINUTE_STATE_TIME; shmp->caller_info.fee = mosms_unit_charge * charge_num; shmp->called_info.fee = 0x00; } else { shmp->caller_info.valid_time = 0; /* should be a parameter */ shmp->called_info.valid_time = 0; shmp->process_info.tcos = CALLER_CREDIT_OUT; /* no enough balance */ } break; default: shmp->caller_info.valid_time = 0; shmp->called_info.valid_time = 0; shmp->process_info.tcos = CALLER_CREDIT_OUT; break; } return bundle_used_num; } int ConferenceCallBillingProc(_state_data *shmp,int duration) { float charge,balance; int unit_time=60,unit_amount,tariff_id=0; int cos_id; COSTable *cosTableItem; PutLogFunID("ConferenceCallBillingProc"); tariff_id = GetAccountZoneID(shmp->caller_info.head,shmp->caller_info.tail); if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; if(shmp->caller_info.status != T_NORMAL || tvnow.tv_sec>= GetExpiration(&shmp->caller_info)) return FALSE; cos_id = shmp->caller_info.cos_id; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; unit_time = blf_shmp->comm_tariff[tariff_id].ccChargeUnit; if(unit_time<=0) unit_time = 60; unit_amount = blf_shmp->comm_tariff[tariff_id].ccChargeAmount; if(unit_amount<=0) unit_amount = 20; if(cosTableItem->serviceControl[0].moThresholdSet) balance = GetBalanceWithPromotionControl(shmp,&shmp->caller_info) + GetOverdraft(&shmp->caller_info) - cosTableItem->serviceControl[0].moMinimumBalance; if(balance<0) { return FALSE; } balance = GetBalanceWithPromotionControl(shmp,&shmp->caller_info) + GetOverdraft(&shmp->caller_info); charge = (duration * unit_amount*1.0) / unit_time; shmp->caller_info.charge = charge; shmp->caller_info.fee = charge; if(balance>=charge) return TRUE; return FALSE; } void ChangeTariffToCugTariff(_state_data *shmp,_bill_tariff *ptar){ u_short rUnit=60; float rAmount=0; u_short Unit=0; u_char tier; int tariff_id; PutLogFunID("ChangeTariffToCugTariff"); 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 = blf_shmp->comm_tariff[tariff_id].cugChargeUnit; rAmount = blf_shmp->comm_tariff[tariff_id].cugChargeAmount; if(rUnit == 0) rUnit = 60; tier = getCurrentTier(shmp,ptar); ptar->tierRating.rating[tier].base_fee = Unit * rAmount /rUnit; } void ChangeTariffToFavoriteCallTariff(_state_data *shmp,_bill_tariff *ptar) { u_short rUnit=60; float rAmount=0; u_short Unit=0; u_char tier; int tariff_id; PutLogFunID("ChangeTariffToFavoriteCallTariff"); if(shmp->process_info.favoriteCall == FRIEND_FAMILY_FREE_CALL) return; 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 = blf_shmp->comm_tariff[tariff_id].favChargeUnit; rAmount = blf_shmp->comm_tariff[tariff_id].favChargeAmount; if(rUnit ==0) rUnit = 60; tier = getCurrentTier(shmp,ptar); ptar->tierRating.rating[tier].base_fee = Unit * rAmount /rUnit; } void ChangeTariffToMORoamingTariff(_state_data *shmp,_bill_tariff *ptar){ u_short rUnit,Unit=0; float rAmount,Amount=0; u_char tier; int tariff_id; _bill_tariff const *moPtr; PutLogFunID("ChangeTariffToMORoamingTariff"); moPtr = shmp->process_info.tariffMoReadOnly; if(moPtr == NULL) { pps_print_error(shmp->process_info.logMsisdn,"[%05d]ChangeTariffToMORoamingTariff,no mo tariff", shmp->process_info.portid); return; } tariff_id = shmp->caller_info.location; Unit = moPtr->unit_time; if(Unit == 0) Unit = 60; tier = getCurrentTier(shmp, (_bill_tariff *)moPtr); Amount = moPtr->tierRating.rating[tier].base_fee; if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; rUnit = blf_shmp->comm_tariff[tariff_id].roamingChargeUnit; rAmount = blf_shmp->comm_tariff[tariff_id].roamingChargeAmount; if(rUnit ==0) rUnit = 60; ptar->tierRating.rating[tier].base_fee = Unit * rAmount /rUnit + Amount; } void ChangeTariffToMTRoamingTariff(_state_data *shmp,_bill_tariff *ptar) { u_short rUnit,Unit; float rAmount,base_fee; int location; char destination[128],inter_prefix[32]; u_char tier,tierDest; _bill_tariff *ptrTemp,btar; _bill_tariff const *mtPtr; PutLogFunID("ChangeTariffToMTRoamingTariff"); memset(&btar,0,sizeof(_bill_tariff)); ptrTemp = &btar; mtPtr = shmp->process_info.tariffMtReadOnly; if(mtPtr == NULL) { pps_print_error(shmp->process_info.logMsisdn,"[%05d]ChangeTariffToMTRoamingTariff,no mt tariff", shmp->process_info.portid); return; } location = GetAccountZoneID(shmp->called_info.head, shmp->called_info.tail); xap_get_interprefix((u8 *)inter_prefix); BcdToAscii(destination, (BYTE *)inter_prefix, 4); StringCut(destination,'E'); strcat(destination,shmp->cdr_info.locationNumber); shmp->process_info.tariff_flag = GetMOTariffData(shmp,ptrTemp, destination, location); if(shmp->process_info.tariff_flag <= 0) { pps_print_error(shmp->process_info.logMsisdn,"[%05d]ChangeTariffToMTRoamingTariff,can't find prefix by:%s,assume basic fee and long fee as 0", shmp->process_info.portid,destination); } location = shmp->called_info.location; rUnit = blf_shmp->comm_tariff[location].roamingChargeUnit; rAmount = blf_shmp->comm_tariff[location].roamingChargeAmount; if(rUnit ==0) rUnit = 60; Unit = mtPtr->unit_time; if(Unit == 0) Unit = 60; tier = getCurrentTier(shmp, (_bill_tariff *)mtPtr); tierDest = getCurrentTier(shmp,ptrTemp); base_fee = mtPtr->tierRating.rating[tier].base_fee; ptar->tierRating.rating[tier].base_fee = base_fee + Unit * rAmount /rUnit; Unit = ptrTemp->unit_time; if(Unit == 0) Unit = 60; rUnit = mtPtr->unit_time; if(rUnit == 0) rUnit = 60; if(UnittierRating.rating[tier].long_distance_fee = mtPtr->tierRating.rating[tier].long_distance_fee + ptrTemp->tierRating.rating[tierDest].long_distance_fee*rUnit/Unit; } else { ptar->tierRating.rating[tier].long_distance_fee = ptrTemp->tierRating.rating[tierDest].long_distance_fee + mtPtr->tierRating.rating[tier].long_distance_fee * Unit / rUnit; ptar->tierRating.rating[tier].base_fee = ptar->tierRating.rating[tier].base_fee * Unit / rUnit; ptar->adjustment = mtPtr->adjustment * Unit / rUnit; ptar->unit_time = mtPtr->unit_time * Unit / rUnit; ptar->mini_unit = ptrTemp->mini_unit; } } void ChangeTariffToCfTariff(_state_data *shmp,_bill_tariff *ptar){ u_short cfUnit; float cfAmount; u_short Unit=0; u_char tier; int tariff_id; PutLogFunID("ChangeTariffToCfTariff"); 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; cfUnit = blf_shmp->comm_tariff[tariff_id].cfChargeUnit; cfAmount = blf_shmp->comm_tariff[tariff_id].cfChargeAmount; if(cfUnit ==0) cfUnit = 60; tier = getCurrentTier(shmp,ptar); ptar->tierRating.rating[tier].base_fee = Unit * cfAmount /cfUnit; } void ChangeTariffToCfCugTariff(_state_data *shmp,_bill_tariff *ptar){ u_short cfUnit; float cfAmount; u_short Unit=0; u_char tier; int tariff_id; PutLogFunID("ChangeTariffToCfCugTariff"); 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; cfUnit = blf_shmp->comm_tariff[tariff_id].cf_cugChargeUnit; cfAmount = blf_shmp->comm_tariff[tariff_id].cf_cugChargeAmount; if(cfUnit ==0) cfUnit = 60; tier = getCurrentTier(shmp,ptar); ptar->tierRating.rating[tier].base_fee = Unit * cfAmount /cfUnit; } void ChangeTariffToCfFavTariff(_state_data *shmp,_bill_tariff *ptar){ u_short cfUnit; float cfAmount; u_short Unit=0; u_char tier; int tariff_id; PutLogFunID("ChangeTariffToCfFavTariff"); 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; cfUnit = blf_shmp->comm_tariff[tariff_id].cf_favChargeUnit; cfAmount = blf_shmp->comm_tariff[tariff_id].cf_favChargeAmount; if(cfUnit ==0) cfUnit = 60; tier = getCurrentTier(shmp,ptar); ptar->tierRating.rating[tier].base_fee = Unit * cfAmount /cfUnit; } void ChangeTariffToCugFavTariff(_state_data *shmp,_bill_tariff *ptar){ u_short cfUnit; float cfAmount; u_short Unit=0; u_char tier; int tariff_id; PutLogFunID("ChangeTariffToCugFavTariff"); 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; cfUnit = blf_shmp->comm_tariff[tariff_id].cug_favChargeUnit; cfAmount = blf_shmp->comm_tariff[tariff_id].cug_favChargeAmount; if(cfUnit ==0) cfUnit = 60; tier = getCurrentTier(shmp,ptar); ptar->tierRating.rating[tier].base_fee = Unit * cfAmount /cfUnit; } void ChangeTariffToCfCugFavTariff(_state_data *shmp,_bill_tariff *ptar){ u_short cfUnit; float cfAmount; u_short Unit=0; u_char tier; int tariff_id; PutLogFunID("ChangeTariffToCfCugFavTariff"); 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; cfUnit = blf_shmp->comm_tariff[tariff_id].cf_cug_favChargeUnit; cfAmount = blf_shmp->comm_tariff[tariff_id].cf_cug_favChargeAmount; if(cfUnit ==0) cfUnit = 60; tier = getCurrentTier(shmp,ptar); ptar->tierRating.rating[tier].base_fee = Unit * cfAmount /cfUnit; } int GetMTTariffData(_state_data *shmp, u_char tariffID, _bill_tariff *ptar, _account_info *pinfo, _account_info *pcaller) { int prefixIndex = DEFAULT_MT_BILLING,i; int len=0,maxlen=0; _bill_tariff *ptr; int cos_id; COSTable *cosTableItem; PutLogFunID("GetMTTariffData"); cos_id = pinfo->cos_id; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; if(cosTableItem->serviceControl[0].mtChargeFlag==0) { ptar->call_type = 4; ptar->free_time = 0; ptar->unit_time = 60; ptar->mini_unit = 1; ptar->adjustment = 0; memset(&ptar->tierRating,0,sizeof(TIER_RATING)); return 1; } if(tariffID>=MAX_ZONE_NUM ) tariffID = 0; memset(ptar,0,sizeof(_bill_tariff)); for(i=1;icalled_tariff[tariffID][i]; if(ptr->bill_id[0] == 0) continue; len = strlen(ptr->bill_id); if(len>maxlen) if(!strncasecmp((char *)pcaller->number,ptr->bill_id,len)) { maxlen = len; prefixIndex = i; } } memcpy(ptar,&blf_shmp->called_tariff[tariffID][prefixIndex],sizeof(_bill_tariff)); shmp->process_info.tariffMtReadOnly = &blf_shmp->called_tariff[tariffID][prefixIndex]; return 1; } int cfLargeThancug(int tariff_id) { _comm_tariff *commTariff; PutLogFunID("cfLargeThancug"); if(tariff_id>=MAX_ZONE_NUM || tariff_id<0) tariff_id = 0; commTariff = &ramshm_ptr->tariff_data.comm_tariff[tariff_id]; if((commTariff->cfChargeAmount*commTariff->cugChargeUnit)> (commTariff->cugChargeAmount*commTariff->cfChargeUnit)) return 1; else return 0; } int BillingProc(_state_data *shmp, int sub_flag0) { int duration=0,overdraft=0,sub_flag; int cos_id; COSTable *cosTableItem; CosServiceControl *serviceControlItem = NULL, *mtServiceCtrItem = NULL; PutLogFunID("BillingProc"); sub_flag = sub_flag0; cos_id = shmp->caller_info.cos_id; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; serviceControlItem = &cosTableItem->serviceControl[0]; if (sub_flag || shmp->process_info.favoriteCall == FRIEND_FAMILY_FREE_CALL) { if(shmp->context_info.callType == CT_MT_CALL) { shmp->process_info.tariff_flag = GetMTTariffData(shmp, shmp->called_info.location, &shmp->process_info.tariff, &shmp->called_info, &shmp->charge_info); } else { if(shmp->process_info.serviceType == SRV_CRD || (shmp->process_info.serviceType == SRV_NORMAL_MO_CALL && shmp->process_info.callConnected == 1 && !ppsParam.serviceControl.vms_allways_go)) { GetMOTariffData(shmp, &shmp->process_info.tariff, (char *)shmp->charge_info.number, shmp->caller_info.location); shmp->process_info.tariff_flag = 1; shmp->caller_info.valid_time = 12*ONE_MINUTE_STATE_TIME; shmp->caller_info.fee = 0; shmp->called_info.valid_time = 12*ONE_MINUTE_STATE_TIME; shmp->called_info.fee = 0; return 1; } if(shmp->context_info.callType == CT_MO_CALL && cosTableItem->smsNotificationInquiry[0].smsNotificationWhenBalanceInsufficient) if(GetBalanceWithPromotionControl(shmp,&shmp->caller_info)< cosTableItem->smsNotificationInquiry[0].insufficientBalanceThreshold) { shmp->process_info.pre_warning = 1; shmp->process_info.voiceID = PRE_WARNING_LOW_BALANCE; } if(shmp->process_info.mnp_status) { char billing_prefix[64]; sprintf(billing_prefix,"%s%s",shmp->process_info.routing_number, shmp->called_info.number); shmp->process_info.tariff_flag = GetMOTariffData(shmp,&shmp->process_info.tariff, billing_prefix, shmp->caller_info.location); /* parameter: continue or release the call */ if(shmp->process_info.tariff_flag==0) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\33[33m Calling ported number, but no RN+MSISDN(%s) billing prefix\33[0m", billing_prefix); DebugMsg(debugmib.display.asciiOut, "\33[33m Use dialing prefix %s as billing prefix\33[0m", shmp->charge_info.number); } shmp->process_info.tariff_flag = GetMOTariffData(shmp, &shmp->process_info.tariff, (char *)shmp->charge_info.number, shmp->caller_info.location); } else { strcpy((char *)shmp->charge_info.number, billing_prefix); } } else { shmp->process_info.tariff_flag = GetMOTariffData(shmp,&shmp->process_info.tariff, (char *)shmp->charge_info.number, shmp->caller_info.location); } /* check MO tariff cap flag here */ /* added for cap call, 2007-10-25 */ shmp->process_info.cap_flag = shmp->process_info.tariff.cap_flag; // Check Cap or Bundle is used================================ if(serviceControlItem->cap_or_bundle_in_tariff)// bundle is used, so we can set bundle flag and clear cap flag { shmp->process_info.bundle_flag = shmp->process_info.cap_flag; /* cap flag is reused as bundle call */ shmp->process_info.cap_flag = 0; } //================================================== if(shmp->process_info.cap_flag>0) { // DebugMsg(debugmib.display.asciiOut,"CAP call, flag: %d", // shmp->process_info.cap_flag); shmp->caller_info.location = GetSubsCapTariffID(shmp,CAP_CALL); GetMOTariffData(shmp,&shmp->process_info.tariff, (char *)shmp->charge_info.number, shmp->caller_info.location); } if(shmp->process_info.favoriteCall) { if(CheckFriendFamilyPlanFreeCallOrSMS(shmp->caller_info.head, shmp->caller_info.tail, 0, shmp->process_info.duration/CYCLE_STATE_INTERVAL)) { shmp->process_info.favoriteCall = FRIEND_FAMILY_FREE_CALL; memset(&shmp->process_info.tariff.tierRating, 0x00, sizeof(TIER_RATING)); shmp->process_info.tariff.adjustment = 0; shmp->process_info.tariff.cap_flag = 0; } else { IncreaseFriendFamilyFreeCallDuration(shmp->caller_info.head, shmp->caller_info.tail, shmp->process_info.duration); shmp->process_info.favoriteCall = FRIEND_FAMILY_CALL; } } if(serviceControlItem->moThresholdSet && shmp->process_info.favoriteCall != FRIEND_FAMILY_FREE_CALL) { if((GetBalanceWithPromotionControl(shmp,&shmp->caller_info)+GetOverdraft(&shmp->caller_info)) < (serviceControlItem->moMinimumBalance)) { shmp->caller_info.valid_time = 0; shmp->caller_info.fee = 0; shmp->called_info.valid_time = 0; shmp->called_info.fee = 0; return 0; } } } }// if sub_flag switch(shmp->context_info.callType){ case CT_MT_CALL: switch(shmp->called_info.status) { case T_FRESH: case T_SUSPEND: case T_BLACKLIST: case T_EXTERNAL: case T_RELEASED: shmp->caller_info.valid_time = 0; shmp->called_info.valid_time = 0; shmp->process_info.tcos = CALLED_STATUS_ERROR; shmp->process_info.voiceID = MT_ERROR_ACCOUNT_STATUS; return FALSE; break; default: break; } // Check Cap or Bundle is used================================ mtServiceCtrItem = &ppsParam.ppsTables.cosTable[shmp->called_info.cos_id].serviceControl[0]; if(mtServiceCtrItem->cap_or_bundle_in_tariff)// bundle is used, so we can set bundle flag { shmp->process_info.bundle_flag = shmp->process_info.tariff.cap_flag; } //================================================== if(shmp->process_info.bundle_flag) { int left_mt_voice_seconds = 0; left_mt_voice_seconds = pps_get_account_bundle_mt_voice(shmp); if(left_mt_voice_seconds > 0) { if(left_mt_voice_seconds > shmp->process_info.tariff.unit_time) left_mt_voice_seconds = shmp->process_info.tariff.unit_time; shmp->caller_info.valid_time = left_mt_voice_seconds*CYCLE_STATE_INTERVAL; shmp->caller_info.fee = 0; shmp->called_info.fee = 0; shmp->called_info.valid_time = shmp->caller_info.valid_time; //DebugMsg(debugmib.display.asciiOut, "BillingProc()->%s allocate bundle mt voice[%d]", // shmp->caller_info.number, left_mt_voice_seconds); return 1; } else { /* if(shmp->process_info.duration > 1) { subscribe_bundle_plan_send_used_up_info(shmp->caller_info.number, SMS_BUNDLE_PLAN_VOICE_USEDUP); } */ shmp->process_info.bundle_flag = 0; } } if(shmp->process_info.chargedTime==0 && shmp->process_info.tariff.free_time) { shmp->called_info.valid_time = shmp->process_info.tariff.free_time*CYCLE_STATE_INTERVAL; shmp->called_info.fee = 0; } else { sub_flag = shmp->process_info.chargedTime; if(shmp->process_info.tariff.free_time) sub_flag = shmp->process_info.chargedTime - 1; overdraft = GetOverdraft(&shmp->called_info); if(!sub_flag && overdraft<0){ overdraft = 0; } shmp->called_info.valid_time = GetValidTime( shmp, tvnow.tv_sec, //shmp->cdr_info.answertime, &shmp->process_info.tariff, GetBalanceWithPromotionControl(shmp,&shmp->called_info), sub_flag, overdraft); duration = (int)( shmp->called_info.valid_time / CYCLE_STATE_INTERVAL); shmp->called_info.fee = TimeToCharge(shmp,&shmp->process_info.tariff, duration, tvnow.tv_sec,sub_flag); if(isPoolChildReachFeeLimit(&shmp->called_info) == 2) { pps_print_error(shmp->process_info.logMsisdn,"%s child account,reach limited fee",shmp->called_info.number); shmp->caller_info.valid_time = 0; shmp->caller_info.fee = 0; shmp->called_info.valid_time = 0; shmp->called_info.fee = 0; shmp->process_info.tcos = CALLER_REACH_CHARGE_LIMIT; shmp->process_info.pre_warning = 1; shmp->process_info.voiceID = PRE_WARNING_LOW_BALANCE; return -1; } } shmp->caller_info.fee = 0; shmp->caller_info.valid_time = shmp->called_info.valid_time; break; case CT_MF_CALL: case CT_MO_CALL: if(shmp->process_info.serviceType == SRV_CRD || (shmp->process_info.serviceType == SRV_NORMAL_MO_CALL && shmp->process_info.callConnected == 1 && !ppsParam.serviceControl.vms_allways_go)) { shmp->process_info.tariff_flag = 1; shmp->caller_info.valid_time = 6*ONE_MINUTE_STATE_TIME; shmp->caller_info.fee = 0; shmp->called_info.valid_time = 6*ONE_MINUTE_STATE_TIME; shmp->called_info.fee = 0; return 1; } switch(shmp->caller_info.status) { case T_FRESH: case T_SUSPEND: case T_BLACKLIST: case T_EXTERNAL: case T_RELEASED: shmp->caller_info.valid_time = 0; shmp->called_info.valid_time = 0; shmp->process_info.tcos = CALLER_STATUS_ERROR; shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; return FALSE; break; default: break; } overdraft = GetOverdraft(&shmp->caller_info); if(shmp->process_info.bundle_flag )/* bundle mo call charging */ { int left_mo_voice_seconds = 0; left_mo_voice_seconds = pps_get_account_bundle_mo_voice(shmp); if(left_mo_voice_seconds > 0) { if(left_mo_voice_seconds > shmp->process_info.tariff.unit_time) left_mo_voice_seconds = shmp->process_info.tariff.unit_time; shmp->caller_info.valid_time = left_mo_voice_seconds*CYCLE_STATE_INTERVAL; shmp->caller_info.fee = 0; shmp->called_info.fee = 0; shmp->called_info.valid_time = shmp->caller_info.valid_time; //DebugMsg(debugmib.display.asciiOut, "BillingProc()->%s allocate bundle mo voice[%d]", // shmp->caller_info.number, left_mo_voice_seconds); return 1; } else { /* if(shmp->process_info.duration > 1) { subscribe_bundle_plan_send_used_up_info(shmp->caller_info.number, SMS_BUNDLE_PLAN_VOICE_USEDUP); } */ shmp->process_info.bundle_flag = 0; } } if(shmp->process_info.chargedTime==0 && shmp->process_info.tariff.free_time) { shmp->caller_info.valid_time = shmp->process_info.tariff.free_time*CYCLE_STATE_INTERVAL; shmp->caller_info.fee = 0; if(GetBalanceWithPromotionControl(shmp,&shmp->caller_info)+overdraft< getCurrentFee(shmp)) { shmp->caller_info.valid_time = 0; } } else { if(shmp->process_info.cap_flag>0 && sub_flag0 == 0) /* re-get tariff for cap call during the call */ { shmp->caller_info.location = GetSubsCapTariffID(shmp,CAP_CALL); GetMOTariffData(shmp,&shmp->process_info.tariff, (char *)shmp->charge_info.number, shmp->caller_info.location); } sub_flag = shmp->process_info.chargedTime; if(shmp->process_info.tariff.free_time) sub_flag = shmp->process_info.chargedTime - 1; if(!sub_flag && overdraft<0){ overdraft = 0; } shmp->caller_info.valid_time = GetValidTime( shmp, tvnow.tv_sec, //shmp->cdr_info.answertime, &shmp->process_info.tariff, GetBalanceWithPromotionControl(shmp,&shmp->caller_info), sub_flag, overdraft); duration = (int)( shmp->caller_info.valid_time / CYCLE_STATE_INTERVAL); shmp->caller_info.fee = TimeToCharge(shmp,&shmp->process_info.tariff, duration,tvnow.tv_sec,sub_flag); if(isPoolChildReachFeeLimit(&shmp->caller_info) == 2) { pps_print_error(shmp->process_info.logMsisdn,"%s child account,reach limited fee",shmp->caller_info.number); shmp->caller_info.valid_time = 0; shmp->caller_info.fee = 0; shmp->called_info.valid_time = 0; shmp->called_info.fee = 0; shmp->process_info.tcos = CALLER_REACH_CHARGE_LIMIT; shmp->process_info.pre_warning = 1; shmp->process_info.voiceID = PRE_WARNING_LOW_BALANCE; return -1; } } shmp->called_info.fee = 0; shmp->called_info.valid_time = shmp->caller_info.valid_time; break; default: shmp->caller_info.valid_time = 0; shmp->called_info.valid_time = 0; break; } shmp->process_info.chargedTime ++; return SUCCESS; } int crm_check_if_cug_call(_account_info *caller, _account_info *called) { if(caller == NULL || called == NULL) return 0; if(caller->cug_id == 0 || called->cug_id == 0) return 0; if(caller->cug_id != called->cug_id) return 0; return 1; } extern int ocs_get_crm_free_seconds(); int BillingProc_crm(_state_data *shmp, int sub_flag0) { int duration=0,overdraft=0,sub_flag; int cos_id; COSTable *cosTableItem; //CosServiceControl *mtServiceCtrItem = NULL;//*serviceControlItem = NULL, char prefix[128], areaName[32]=""; PutLogFunID("BillingProc_crm"); sub_flag = sub_flag0; cos_id = shmp->caller_info.cos_id; cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; //serviceControlItem = &cosTableItem->serviceControl[0]; if(shmp->context_info.callType == CT_MT_CALL) { switch(shmp->called_info.status) { case T_FRESH: //case T_SUSPEND: case T_BLACKLIST: case T_EXTERNAL: case T_DISABLE: case T_RELEASED: shmp->caller_info.valid_time = 0; shmp->called_info.valid_time = 0; shmp->process_info.tcos = CALLER_STATUS_ERROR; shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; return FALSE; break; default: break; } shmp->process_info.tariff_flag = 1; shmp->caller_info.valid_time = 12*ONE_MINUTE_STATE_TIME; shmp->caller_info.fee = 0; shmp->called_info.valid_time = 12*ONE_MINUTE_STATE_TIME; shmp->called_info.fee = 0; shmp->process_info.call_type = CT_LOCAL_CALL_IN; if(ocs_get_charge_prefix( (char *)shmp->caller_info.number, prefix, areaName, &shmp->process_info.tariff.call_type) == 0) return 1; if(shmp->process_info.tariff.call_type == CT_LOCAL_CALL_OUT) //to get incoming call type { shmp->process_info.tariff.call_type = CT_LOCAL_CALL_IN; shmp->process_info.call_type = CT_LOCAL_CALL_IN; } else if(shmp->process_info.tariff.call_type == CT_TRUNK_CALL_OUT) { shmp->process_info.tariff.call_type = CT_TRUNK_CALL_IN; shmp->process_info.call_type = CT_TRUNK_CALL_IN; } else if(shmp->process_info.tariff.call_type == CT_IDD_CALL_OUT) { shmp->process_info.tariff.call_type = CT_IDD_CALL_IN; shmp->process_info.call_type = CT_IDD_CALL_IN; } return 1; } if(shmp->process_info.rest_if.query_tariff_status == 2) { shmp->process_info.tariff_flag = 1; shmp->process_info.tariff.unit_time = shmp->process_info.rest_if.unit; shmp->process_info.tariff.tierRating.tierNumber = 0; shmp->process_info.tariff.tierRating.rating[0].base_fee = shmp->process_info.rest_if.unit_charge; shmp->process_info.tariff.tierRating.rating[0].units = 1; shmp->process_info.tariff.tierRating.rating[0].long_distance_fee = 0; shmp->process_info.tariff.mini_unit = 1; } else { shmp->process_info.tariff_flag = 0; } switch(shmp->caller_info.status) { case T_FRESH: case T_SUSPEND: case T_BLACKLIST: case T_EXTERNAL: case T_DISABLE: case T_RELEASED: shmp->process_info.tariff_flag = 1; shmp->caller_info.valid_time = 0; shmp->called_info.valid_time = 0; shmp->process_info.tcos = CALLER_STATUS_ERROR; shmp->process_info.voiceID = ERROR_ACCOUNT_STATUS; shmp->process_info.pre_warning = 1; return FALSE; break; default: break; } if(crm_check_if_cug_call(&shmp->caller_info, &shmp->called_info)) //if(shmp->caller_info.cug_id>0 && (shmp->caller_info.cug_id == shmp->called_info.cug_id )) { shmp->process_info.tariff_flag = 1; shmp->caller_info.valid_time = 120*ONE_MINUTE_STATE_TIME; shmp->caller_info.fee = 0; shmp->called_info.valid_time = 120*ONE_MINUTE_STATE_TIME; shmp->called_info.fee = 0; return 1; } shmp->caller_info.free_flag = 0; if(shmp->context_info.callType == CT_MO_CALL && cosTableItem->smsNotificationInquiry[0].smsNotificationWhenBalanceInsufficient) { if(GetBalanceWithPromotionControl(shmp,&shmp->caller_info)< cosTableItem->smsNotificationInquiry[0].insufficientBalanceThreshold) { shmp->process_info.pre_warning = 1; shmp->process_info.voiceID = PRE_WARNING_LOW_BALANCE; } } else { if ((shmp->process_info.rest_if.total_plan_value> 0) && (shmp->process_info.rest_if.used_plan_value < shmp->process_info.rest_if.total_plan_value)) { if(sub_flag) { if(shmp->process_info.tariff.call_type != CT_IDD_CALL_OUT) { int free_secs = ocs_get_crm_free_seconds(); if(free_secs>0) { shmp->caller_info.free_flag = 1; shmp->caller_info.valid_time = free_secs*CYCLE_STATE_INTERVAL; shmp->caller_info.fee = 0; shmp->called_info.valid_time = shmp->caller_info.valid_time; shmp->called_info.fee = 0; return 1; } } } int left_plan_value = 0; left_plan_value = (shmp->process_info.rest_if.total_plan_value - shmp->process_info.rest_if.used_plan_value); if(left_plan_value > shmp->process_info.tariff.unit_time) left_plan_value = shmp->process_info.tariff.unit_time; shmp->caller_info.valid_time = (left_plan_value) * CYCLE_STATE_INTERVAL; shmp->caller_info.fee = 0; goto billing_crm_ret; } { shmp->caller_info.valid_time = GetValidTime( shmp, tvnow.tv_sec, &shmp->process_info.tariff, GetBalanceWithPromotionControl(shmp,&shmp->caller_info), sub_flag, overdraft); duration = (int)( shmp->caller_info.valid_time/CYCLE_STATE_INTERVAL); shmp->caller_info.fee = TimeToCharge(shmp,&shmp->process_info.tariff, duration,tvnow.tv_sec,sub_flag); } if(sub_flag && (shmp->caller_info.valid_time) > CYCLE_STATE_INTERVAL) { if(shmp->process_info.tariff.call_type != CT_IDD_CALL_OUT) { int free_secs = ocs_get_crm_free_seconds(); if(free_secs>0) { shmp->caller_info.free_flag = 1; shmp->caller_info.valid_time = free_secs*CYCLE_STATE_INTERVAL; shmp->caller_info.fee = 0; shmp->called_info.valid_time = shmp->caller_info.valid_time; shmp->called_info.fee = 0; return 1; } } } } billing_crm_ret: shmp->called_info.fee = 0; shmp->called_info.valid_time = shmp->caller_info.valid_time; shmp->process_info.chargedTime ++; return SUCCESS; } extern float ocs_get_calling_card_left_balance(int head, int tail); int BillingProc_ccc(_state_data *shmp, int sub_flag0) { int duration=0,overdraft=0,sub_flag; //int cos_id; //COSTable *cosTableItem; //CosServiceControl *serviceControlItem = NULL, *mtServiceCtrItem = NULL; int balance = 0; PutLogFunID("BillingProc_ccc"); sub_flag = sub_flag0; //cos_id = shmp->caller_info.cos_id; //cosTableItem = &ppsParam.ppsTables.cosTable[cos_id]; //serviceControlItem = &cosTableItem->serviceControl[0]; shmp->caller_info.location = shmp->caller_info.cos_id; if (sub_flag ) { shmp->process_info.tariff_flag = GetMOTariffData(shmp,&shmp->process_info.tariff, (char *)shmp->charge_info.number, shmp->caller_info.location); balance = (int)ocs_get_calling_card_left_balance(shmp->card_info.cardhead, shmp->card_info.cardtail); shmp->card_info.balance = balance; }// if sub_flag else { if(shmp->card_info.balance > shmp->card_info.cc_call_charge) balance = shmp->card_info.balance; else balance = 0; } switch(shmp->context_info.callType){ case CT_MO_CC_CALL: if( shmp->process_info.callConnected == 1 ) { shmp->process_info.tariff_flag = 1; shmp->caller_info.valid_time = 6*ONE_MINUTE_STATE_TIME; shmp->caller_info.fee = 0; shmp->called_info.valid_time = 6*ONE_MINUTE_STATE_TIME; shmp->called_info.fee = 0; return 1; } if(shmp->process_info.chargedTime==0 && shmp->process_info.tariff.free_time) { shmp->caller_info.valid_time = shmp->process_info.tariff.free_time*CYCLE_STATE_INTERVAL; shmp->caller_info.fee = 0; } else { if(shmp->process_info.cap_flag>0 && sub_flag0 == 0) /* re-get tariff for cap call during the call */ { GetMOTariffData(shmp,&shmp->process_info.tariff, (char *)shmp->charge_info.number, shmp->caller_info.location); } sub_flag = shmp->process_info.chargedTime; if(shmp->process_info.tariff.free_time) sub_flag = shmp->process_info.chargedTime - 1; shmp->caller_info.valid_time = GetValidTime( shmp, tvnow.tv_sec, &shmp->process_info.tariff, balance, sub_flag, overdraft); duration = (int)( shmp->caller_info.valid_time / CYCLE_STATE_INTERVAL); shmp->caller_info.fee = TimeToCharge(shmp,&shmp->process_info.tariff, duration,tvnow.tv_sec,sub_flag); } shmp->called_info.fee = 0; shmp->called_info.valid_time = shmp->caller_info.valid_time; break; default: shmp->caller_info.valid_time = 0; shmp->called_info.valid_time = 0; break; } shmp->process_info.chargedTime ++; return SUCCESS; } int IsEnableToCall_ccc(int proc_id) { _state_data *shmp=(_state_data *) &smshm_ptr->state_data; //int call_type=0,rst; //COSTable *cosTableItem; PutLogFunID("IsEnableToCall"); shmp += proc_id; //call_type = shmp->context_info.callType; if(shmp->process_info.tcos == SRVICE_NOT_SUBSCRIBERED) return FALSE; if(shmp->process_info.tariff_flag ==0) { shmp->process_info.tcos = TARIFF_NOT_SET; shmp->process_info.voiceID = CALLED_TARIFF_NOT_SET; return FALSE; } if(shmp->caller_info.valid_time <= 0) { shmp->process_info.tcos = CALLER_CREDIT_OUT; shmp->process_info.voiceID = LOW_ACCOUNT_BALANCE; return FALSE; } return TRUE; } void SetCallType(_state_data *shmp, int type) { switch(type) { case 0: if(shmp->context_info.callType == CT_MT_CALL) shmp->process_info.call_type = CT_LOCAL_CALL_IN; else shmp->process_info.call_type = CT_LOCAL_CALL_OUT; break; case 1: shmp->process_info.call_type = CT_NDD_CALL_OUT; break; case 2: shmp->process_info.call_type = CT_IDD_CALL_OUT; break; case 4: shmp->process_info.call_type = CT_LOCAL_CALL_IN; break; case 5: shmp->process_info.call_type = CT_TRUNK_CALL_IN; break; default: shmp->process_info.call_type = type; break; } } const int IsNormalRechargeCard(_state_data *shmp) { u_char bcd[CONTEXT_BLOCK_SIZE]; u_long expiration=0; PutLogFunID("IsNormalRechargeCard"); memcpy(bcd, &shmp->context_info.context[1], sizeof(_RCI_)); expiration = ((_RCI_ *)bcd)->expiry_date; if (((_RCI_ *) bcd)->card_status == T_FRESH && (u_long) tvnow.tv_sec < expiration) { return TRUE; } else { return FALSE; } } int GetRechargeCardFaceValue(_state_data *shmp) { u_char bcd[CONTEXT_BLOCK_SIZE]; PutLogFunID("GetRechargeCardFaceValue"); memcpy(bcd, shmp->context_info.context,//+1 , //sizeof(_RSIR_), sizeof(_RCI_)); return ((_RCI_ *) bcd)->face_value; } int GetRechargeCardValidTime(_state_data *shmp) { u_char bcd[CONTEXT_BLOCK_SIZE]; PutLogFunID("GetRechargeCardValidTime"); memcpy(bcd, shmp->context_info.context,//+1, //+sizeof(_RSIR_), sizeof(_RCI_)); return ((_RCI_ *) bcd)->valid_time; } static void PureDigitAscii(u_char *string) { int loop,len; len = strlen((char *)string); for(loop=0;loop'9') { string[loop] = 0; break; } } string[loop] = 0; } char GetTariffLacInfo(u_char *cgi) { int loc = -1, loop, matchFlag=0,len; u_short cell, lac; u_char MCC[32]={0},MNC[32]={0}; BasicTariffZone *pBTZ; PutLogFunID("GetTariffLacInfo"); ppsBcdToAsciiR((char *)MCC,cgi,4); PureDigitAscii(MCC); ppsBcdToAsciiR((char *)MNC,&cgi[2],2); PureDigitAscii(MNC); lac = cgi[3] * 256 + cgi[4]; cell = cgi[5] * 256 + cgi[6]; if(cgi[0]==0 && lac==0 && cell==0) //CF /MT call return loc; for(loop=0;loopexistFlag == FALSE) continue; matchFlag = 0; len = strlen((char *)pBTZ->mcc); if(len == 0) continue; if(memcmp(pBTZ->mcc,MCC,len) == 0) { len = strlen((char *)pBTZ->mnc); if(len == 0) { matchFlag = 1; } else if(memcmp(pBTZ->mnc,MNC,len) ==0 ) { if(ppsParam.serviceControl.charge_by_lac_flag == 1) { if(pBTZ->cellId == cell) matchFlag = 1; } else { if(pBTZ->lac != 0xFFFF) { if(pBTZ->cellId != 0xFFFF) { if(pBTZ->cellId == cell && pBTZ->lac == lac) { matchFlag = 1; } } else if(pBTZ->lac == lac) { matchFlag = 1; } } else { matchFlag = 1; }/* lac */ } }/* mcc&mnc */ if(matchFlag) { return loop; } }//if mcc }/* for */ return loc; } int GetAccountZoneIDByLocationInfo(int index) { return ppsParam.ppsTables.basicTariffZone[index].moTariffId%MAX_ZONE_NUM; } int GetAccountMTZoneIDByLocationInfo(int index) { return ppsParam.ppsTables.basicTariffZone[index].mtTariffId%MAX_ZONE_NUM; } void CheckWetherRoamingUser(_state_data *shmp) { _prepaid_data *user_shmp=&ramshm_ptr->prepaid_data; _account_info *ptr; int loop; PutLogFunID("CheckWetherRoamingUser"); ptr = &shmp->caller_info; shmp->process_info.roamingFlag = 1; if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { for(loop=0;looplocation == user_shmp->prepaid_info[ptr->head][ptr->tail].home_location[loop]) { shmp->process_info.roamingFlag = 0; return; } } } pps_print_event(shmp->process_info.logMsisdn,"%s is a MO roaming user",shmp->caller_info.number); } void CheckWetherRoamingMTUser(_state_data *shmp) { _prepaid_data *user_shmp=&ramshm_ptr->prepaid_data; _account_info *ptr; int loop; PutLogFunID("CheckWetherRoamingMTUser"); ptr = &shmp->called_info; shmp->process_info.roamingFlag = 1; if (ptr->head < MSISDN_HEAD_NUM && ptr->tail < UNIT_STORE_ACCOUNT) { for(loop=0;looplocation == user_shmp->prepaid_info[ptr->head][ptr->tail].home_location[loop]) { shmp->process_info.roamingFlag = 0; return; } } } pps_print_event(shmp->process_info.logMsisdn,"%is a MT roaming user",shmp->called_info.number); } /* get HPLMN from xapp , 2003-10-23 */ void SetRoamingFlag(_state_data *shmp) { char plmn[32]={""},buf[32]={""}; int plmnlen; u_char CC[32],NDC[32]; PutLogFunID("SetRoamingFlag"); xap_get_cc(CC); xap_get_ndc(NDC); BcdToAscii(plmn,CC,4); StringCut(plmn,'E'); BcdToAscii(buf,NDC,6); StringCut(buf,'E'); strcat(plmn,buf); plmnlen = strlen(plmn); if(!strncasecmp(shmp->cdr_info.locationNumber,plmn,plmnlen)) { shmp->process_info.roamingFlag = 0; }else{ shmp->process_info.roamingFlag = 1; } } void SetLocationInfo(u_char *cgi, u_short proc_id) { _state_data *shmp=(_state_data *) &smshm_ptr->state_data; PutLogFunID("SetLocationInfo"); shmp += proc_id; memcpy(shmp->cdr_info.cgi,cgi,7); } u_long GetTimeFunnel(u_short hour, u_short minute, u_short second) { int funnel=0; PutLogFunID("GetTimeFunnel"); funnel = ((hour-GetTmHour()) * 60 * 60 ) + ((minute - GetTmMinute() ) * 60) + (second - GetTmSecond()); return (funnel <= 0) ? (funnel+24*60*60)*CYCLE_STATE_INTERVAL : funnel*CYCLE_STATE_INTERVAL; } int IsEnablePeriodicCharge(int head, int tail) { _prepaid_info *shmp=NULL; PutLogFunID("IsEnablePeriodicCharge"); shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; if ( shmp->msisdn[MAX_MSISDN_BLEN-1] != 0 && ((shmp->status == T_NORMAL ) || (shmp->status == T_BLACKLIST) || (shmp->status == T_SUSPEND )) && shmp->mt_expiration_date>=tvnow.tv_sec && shmp->rent_type != 0) return TRUE; else return FALSE; } int IsEnablePeriodicAction(int head, int tail) { _prepaid_info *shmp=NULL; PutLogFunID("IsEnablePeriodicAction"); shmp = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; if ( shmp->msisdn[MAX_MSISDN_BLEN-1] != 0 && ((shmp->status == T_NORMAL ) || (shmp->status == T_BLACKLIST) || (shmp->status == T_SUSPEND )) && shmp->mt_expiration_date>=tvnow.tv_sec) return TRUE; else return FALSE; } float GetAccountBalance(int head, int tail) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetAccountBalance"); if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) return (shmp->prepaid_info[head][tail].balance + shmp->prepaid_info[head][tail].promo_balance); return FALSE; } int GetAccountVoiceID(int head,int tail) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetAccountVoiceID"); if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) return shmp->prepaid_info[head][tail].language_type; return 0; } int GetUserType(int head, int tail) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetUserType"); if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) return shmp->prepaid_info[head][tail].rent_type; return FAILURE; } int GetPeriodicChargeDate(int tariff_id,int id) { _rent_tariff *shmp=NULL; PutLogFunID("GetPeriodicChargeDate"); if (id < MAX_RENT_TARIFF) { shmp = &ramshm_ptr->tariff_data.rent_tariff[tariff_id][id]; return shmp->charge_date; } else return 32; } int GetPeriodicTariffFee(int tariff_id,int id) { _rent_tariff *shmp=NULL; int rent_amount = 0; PutLogFunID("GetPeriodicTariffFee"); if (id < MAX_RENT_TARIFF) { shmp = &ramshm_ptr->tariff_data.rent_tariff[tariff_id][id]; rent_amount = (int)shmp->rent_amount; } return rent_amount; } short GetPeriodicTariffDate(int tariff_id,int id) { _rent_tariff *shmp=NULL; PutLogFunID("GetPeriodicTariffDate"); if (id < MAX_RENT_TARIFF) { shmp = &ramshm_ptr->tariff_data.rent_tariff[tariff_id][id]; return shmp->charge_date; } else return FAILURE; } short GetPeriodicTariffType(int tariff_id,int id) { _rent_tariff *shmp=NULL; PutLogFunID("GetPeriodicTariffType"); if (id < MAX_RENT_TARIFF) { shmp = &ramshm_ptr->tariff_data.rent_tariff[tariff_id][id]; return shmp->rent_type; } else return FAILURE; } void UpdateAccountBalance(int head, int tail, float charge) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("UpdateAccountBalance"); if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { shmp->prepaid_info[head][tail].balance = shmp->prepaid_info[head][tail].balance + charge; if(shmp->prepaid_info[head][tail].balance<0) { shmp->prepaid_info[head][tail].balance = 0; } } } void UpdateAccountOverdraft(int head, int tail, long overdraft) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("UpdateAccountOverdraft"); if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) shmp->prepaid_info[head][tail].overdraft = overdraft; } void UpdateAccountPromotionBalance(int head, int tail, float charge) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("UpdateAccountPromotionBalance"); if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) shmp->prepaid_info[head][tail].promo_balance = shmp->prepaid_info[head][tail].promo_balance+charge; } void UpdateAccountPromotionExpiryDay(int head, int tail, int days) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("UpdateAccountPromotionExpiryDay"); if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { if(days>0 ) { if(shmp->prepaid_info[head][tail].promo_date< tvnow.tv_sec + days*24*3600) shmp->prepaid_info[head][tail].promo_date = tvnow.tv_sec + days*24*3600; } else shmp->prepaid_info[head][tail].promo_date = shmp->prepaid_info[head][tail].mo_expiration_date; } } void UpdateAccountCUGStatus(_prepaid_info *user_info_ptr, u8 cug_status) { if(user_info_ptr == NULL) return; user_info_ptr->crm_info.vas_cug_state = cug_status; } u_long GetAccountFirstUsedDate(int head, int tail) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetAccountFirstUsedDate"); if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) return shmp->prepaid_info[head][tail].first_used_date; return FALSE; } int MsisdnToLong(u_long *ulmsisdn, char *cmsisdn) { int len,len1; char tmpbuf[64],buf[64]; PutLogFunID("MsisdnToLong"); len = cmsisdn[9]; if(len>18) len = 18; len1 = len; if(len %2 !=0) len1 = len + 1; BcdToAscii(tmpbuf, (BYTE *)cmsisdn,len1); memcpy(buf,tmpbuf,len); buf[len] = 0; *ulmsisdn = atol(buf); return 1; } int GetAccountMsisdnStr(int head, int tail,u_char *msisdn) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; int len; PutLogFunID("GetAccountMsisdn"); if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { len = shmp->prepaid_info[head][tail].msisdn[MAX_MSISDN_BLEN-1]; BcdToAscii((char *)msisdn, shmp->prepaid_info[head][tail].msisdn, (len+1)/2*2); msisdn[len]=0; return TRUE; } return FALSE; } int GetAccountMsisdn(int head, int tail,u_char *msisdn) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; int len; PutLogFunID("GetAccountMsisdn"); if (head < MSISDN_HEAD_NUM && tail < UNIT_STORE_ACCOUNT) { // MsisdnToLong(&msisdn,shmp->prepaid_info[head][tail].msisdn); len = shmp->prepaid_info[head][tail].msisdn[MAX_MSISDN_BLEN-1]; memcpy(msisdn,shmp->prepaid_info[head][tail].msisdn,MAX_MSISDN_BLEN-1); if(len%2==0){ msisdn[len/2]=0xFF; }else{ msisdn[(len)/2] |= 0x0F; } return TRUE; } return FALSE; } void UpdateAccountFirstUsedDate(int head, int tail) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; char date_buf[32]; PutLogFunID("UpdateAccountFirstUsedDate"); GetTmDate(date_buf); strcat(date_buf, "000000"); shmp->prepaid_info[head][tail].first_used_date = MakeTime(NULL, date_buf); } void UpdateAccountStatus(int head, int tail, int status) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("UpdateAccountStatus"); shmp->prepaid_info[head][tail].status = status; } void UpdateAccountRechargeFail(int head, int tail) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("UpdateAccountRechargeFail"); shmp->prepaid_info[head][tail].recharge_fail ++; } u_short GetAccountRechargeFail(int head, int tail) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("GetAccountRechargeFail"); return shmp->prepaid_info[head][tail].recharge_fail; } void ResetAccountRechargeFail(int head, int tail) { _prepaid_data *shmp=&ramshm_ptr->prepaid_data; PutLogFunID("ResetAccountRechargeFail"); shmp->prepaid_info[head][tail].recharge_fail = 0; } int isAccountExpired(_account_info *ptr) { if(GetExpiration(ptr) < tvnow.tv_sec) return 1; return 0; } /* If the call is valid or invalid 0: invalid, 1: valid */ int IsEnableToCall(int proc_id) { _state_data *shmp=(_state_data *) &smshm_ptr->state_data; int call_type=0,rst; COSTable *cosTableItem; PutLogFunID("IsEnableToCall"); shmp += proc_id; call_type = shmp->context_info.callType; if(shmp->process_info.tcos == SRVICE_NOT_SUBSCRIBERED) return FALSE; if(call_type == CT_MO_SM) { rst = isPoolChildReachSMSLimit(shmp); if(rst) { switch(rst) { case 1: shmp->process_info.tcos= CALLER_REACH_SMS_LIMIT; break; case 2: shmp->process_info.tcos= CALLER_REACH_CHARGE_LIMIT; break; } return FALSE; } if ((shmp->caller_info.valid_time > 0 && tvnow.tv_sec <= GetExpiration(&shmp->caller_info))) { return TRUE; } if (tvnow.tv_sec > GetExpiration(&shmp->caller_info) ) { shmp->process_info.tcos= CALLER_EXPIRIED; return FALSE; } else if (shmp->caller_info.valid_time <= 0 ) { shmp->process_info.tcos= CALLER_CREDIT_OUT; return FALSE; } } switch(call_type) { case CT_MT_CALL: if(shmp->called_info.valid_time >0) { SetCallType(shmp,shmp->process_info.tariff.call_type); if(tvnow.tv_sec>=GetIncomingExpiration(&shmp->called_info)) { shmp->process_info.tcos= CALLED_EXPIRIED; shmp->process_info.voiceID = MT_EXPIRIED_ACCOUNT; return FALSE; } else { SetCallType(shmp,shmp->process_info.tariff.call_type); } } else { if(shmp->called_info.status == T_NORMAL) { shmp->process_info.tcos = CALLED_CREDIT_OUT; shmp->process_info.voiceID = MT_LOW_ACCOUNT_BALANCE; } else { shmp->process_info.tcos = CALLED_STATUS_ERROR; shmp->process_info.voiceID = MT_ERROR_ACCOUNT_STATUS; } return FALSE; } if(shmp->process_info.tariff_flag ==0) { shmp->process_info.tcos = TARIFF_NOT_SET; shmp->process_info.voiceID = CALLED_TARIFF_NOT_SET; return FALSE; } break; case CT_MO_CALL: case CT_MF_CALL: if(shmp->process_info.tariff_flag ==0) { shmp->process_info.tcos = TARIFF_NOT_SET; shmp->process_info.voiceID = CALLED_TARIFF_NOT_SET; return FALSE; } if(shmp->caller_info.valid_time >0) { cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; if(tvnow.tv_sec>=GetExpiration(&shmp->caller_info)) { if(call_type == CT_MO_CALL) { shmp->process_info.tcos = CALLER_EXPIRIED; shmp->process_info.voiceID = EXPIRIED_ACCOUNT; } else { shmp->process_info.tcos= CALLED_EXPIRIED; shmp->process_info.voiceID = MT_EXPIRIED_ACCOUNT; } return FALSE; } else if((call_type == CT_MO_CALL) && ((tvnow.tv_sec+ (cosTableItem->smsNotificationInquiry[0].theDaysSendingSMSBeforeExpiredDay)*24*3600) >=GetExpiration(&shmp->caller_info))) { shmp->process_info.pre_warning = 1; shmp->process_info.voiceID = PRE_WARNING_EXPIRATION_DAY; } SetCallType(shmp,shmp->process_info.tariff.call_type); } else { if(shmp->caller_info.status == T_NORMAL) { if(call_type == CT_MO_CALL) { shmp->process_info.tcos = CALLER_CREDIT_OUT; shmp->process_info.voiceID = LOW_ACCOUNT_BALANCE; } else { shmp->process_info.tcos = CALLED_CREDIT_OUT; shmp->process_info.voiceID = MT_LOW_ACCOUNT_BALANCE; } } return FALSE; } break; default: shmp->process_info.tcos = 255; return FALSE; break; } return TRUE; } void SetCSTATimestamp(int instance, u_long timestamp) { PutLogFunID("SetCSTATimestamp"); pps_csta_buffer.csta_record[instance].timestamp = timestamp; } static int callTypeToCstaType(u_short callType) { switch(callType) { case CT_LOCAL_CALL_OUT: case CT_TRUNK_CALL_OUT: case CT_NDD_CALL_OUT: case CT_IDD_CALL_OUT: case CT_LOCAL_CALL_IN: case CT_TRUNK_CALL_IN: case CT_PERIODIC_CHARGE: case CT_ASSISTED_UP: case CT_ASSISTED_DOWN: case CT_RECHARGE_SUCCESS: case CT_RECHARGE_FAIL: case CT_MO_SM: case CT_DIRECT_DEBITING: case CT_REFUND_ACCOUNT: case CT_CONFERENCE_CALL: case CT_THIRD_PARTY_CHARGE: case CT_EMERGENCY_CALL: return callType - PPS_CSTA_TYPE_BASE; break; case CT_BUNDLE_PLAN_CHARGE: return CT_PERIODIC_CHARGE - PPS_CSTA_TYPE_BASE; break; case CT_GPRS: case CT_GPRS_REFUND: return SERVICE_GPRS; break; case CT_MO_CC_CALL: return SERVICE_CCC; default: return -1; break; } return -1; } int CDRStatistics(_tocdr_report* pbuf,float f_charge,ulong gprsVolume) { int charge=0, duration=0; u_short type; char buf[BUFSIZE]; int cstaType; PutLogFunID("CDRStatistics"); type = pbuf->type[0] + pbuf->type[1] * 256; memcpy(&charge , pbuf->charge, 4); memcpy(&duration , pbuf->duration, 4 ); BcdToAscii(buf, pbuf->releasetime, 14); if (type == CT_REFUND_ACCOUNT) { pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.number ++; pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.charge -= charge; reportGprsCDRIncrement(0, -charge, 0); } else if (type == CT_DIRECT_DEBITING) { pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.number ++; pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.charge += charge; reportGprsCDRIncrement(0, charge, 0); } cstaType = callTypeToCstaType(type); if(cstaType<0) return -1; if(cstaType == SERVICE_GPRS) { pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.gprsVolume += gprsVolume; pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.number ++; pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.charge += charge; pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.duration += duration ; } else { pps_csta_buffer.csta_record[csta_old_instance].csta_type[cstaType].number ++; pps_csta_buffer.csta_record[csta_old_instance].csta_type[cstaType].charge += charge; pps_csta_buffer.csta_record[csta_old_instance].csta_type[cstaType].duration += duration ; } AddPPSStatistics(MIBPPS_CSTANUMBER,0); #if DEBUG if(logMsgFlag & 0x04) DebugMsg(debugmib.display.asciiOut, "type:%d charge:%d duration:%d", cstaType, charge, duration); #endif if(cstaType != SERVICE_GPRS) reportCDRIncrement(type, duration, f_charge,gprsVolume); else reportGprsCDRIncrement(duration,f_charge,gprsVolume); return 1; } int GprsCDRStatistics(_tocdr_report* pbuf,float f_charge,ulong gprsVolume) { u_long charge=0, duration=0; u_short type,cstaType; char buf[BUFSIZE]; PutLogFunID("GprsCDRStatistics"); type = pbuf->type[0] + pbuf->type[1] * 256; memcpy(&charge , pbuf->charge, 4); memcpy(&duration , pbuf->duration, 4 ); BcdToAscii(buf, pbuf->releasetime, 14); cstaType = callTypeToCstaType(type); if(cstaType<0) return -1; if( type == CT_GPRS_REFUND) { pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.gprsVolume -= gprsVolume; pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.number --; pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.charge -= charge; pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.duration -= duration ; reportGprsCDRIncrement(duration, -f_charge, -gprsVolume); } else if(cstaType == SERVICE_GPRS) { pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.gprsVolume += gprsVolume; pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.number ++; pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.charge += charge; pps_csta_buffer.csta_record[csta_old_instance].gprsCsta.duration += duration ; reportGprsCDRIncrement(duration,f_charge,gprsVolume); AddPPSStatistics(MIBPPS_CSTANUMBER,0); } #if DEBUG if(logMsgFlag & 0x04) DebugMsg(debugmib.display.asciiOut, "type:%d charge:%d duration:%d volume:%ld", cstaType, charge, duration,gprsVolume); #endif return 1; } int MsisdnToAscii(char *ascii_in, BYTE *cmsisdn) { int len,len1; char tmpbuf[64]; PutLogFunID("MsisdnToAscii"); len = cmsisdn[MAX_MSISDN_BLEN-1]; len = len % 19; len1 = len; if(len%2 !=0) len1 = len + 1; BcdToAscii(tmpbuf,cmsisdn,len1); memcpy(ascii_in,tmpbuf,len); ascii_in[len] = 0; return 1; } int ppsInitCSTA() { time_t nowSec,nowSec1; PutLogFunID("ppsInitCSTA"); nowSec = nowSec1 = tvnow.tv_sec; nowSec = nowSec % (24 * 3600); csta_now_instance = \ csta_old_instance = \ nowSec / (15 * 60); SetCSTATimestamp(csta_old_instance, nowSec1); return 1; } void cstaInstanceCheck() { time_t nowSec,nowSec1; PutLogFunID("cstaInstanceCheck"); nowSec = nowSec1 = tvnow.tv_sec; nowSec = nowSec % (24 * 3600); csta_now_instance = \ nowSec / (15 * 60); if(csta_old_instance != csta_now_instance) { csta_old_instance = csta_now_instance; memset(&pps_csta_buffer.csta_record[csta_now_instance], 0, sizeof(_pps_csta_record)); SetCSTATimestamp(csta_old_instance, nowSec1); } } int CheckWetherLocalNumber(char *number) /*return value is the number property, 0=unknwon, 1=local, 2=national, 3=internationl */ { char plmn[32]={""},buf[BUFSIZE]={""}; char ndc[32]={""},cc[32]={""}; int start,/*len,*/plmnlen,ndclen,cclen; int retval=3; u_char CC[32],NDC[32]; PutLogFunID("CheckWetherLocalNumber"); xap_get_cc(CC); xap_get_ndc(NDC); //len = strlen(number); BcdToAscii(plmn,CC,4); StringCut(plmn,'E'); cclen = strlen(plmn); strcpy(cc,plmn); BcdToAscii(buf,NDC,6); StringCut(buf,'E'); strcpy(ndc,buf); ndclen = strlen(buf); strcat(plmn,buf); plmnlen = strlen(plmn); start = 0; memcpy(buf,number,plmnlen); buf[plmnlen] = 0; if(!strncasecmp(buf,cc,cclen)) { if(!strncasecmp(buf,plmn,plmnlen)) { start += plmnlen; retval = 1; } else { start += cclen; retval = 2; } } else if(ndclen>0 && !strncasecmp(buf,ndc,ndclen)) { start += ndclen; retval = 2; } // if((len-start)<0) start = len; // memcpy(buf,&number[start],len-start); // buf[len-start] = 0; // strcpy(number,buf); return retval; } int transferIddBillingPrefix(char *number) /* to check if idd/00idd billing prefix need to be tranferred by XAPP */ { char inter_prefix[32]; char bufi[32]; int len; PutLogFunID("transferIddBillingPrefix"); xap_get_interprefix((u8 *)inter_prefix); BcdToAscii(bufi, (BYTE *)inter_prefix,4); StringCut(bufi,'E'); len = strlen(bufi); if(memcmp(number,bufi,len)) /* no international prefix */ { return 1; } if(ppsParam.serviceControl.transfer_idd_prefix == 0) /* contains internaltion prefix, e.g 00, but not need to transfer it */ { return 0; } return 1; } int AddNDC(char *number) { char bufndc[32],buf[BUFSIZE]; char NDC[32]; PutLogFunID("AddNDC"); xap_get_ndc((u8 *)NDC); BcdToAscii(bufndc, (BYTE *)NDC,6); StringCut(bufndc,'E'); strcpy(buf,bufndc); strcat(buf,number); strcpy(number,buf); return 1; } int AddCC(char *number) { char bufcc[32],buf[BUFSIZE]; char CC[32]; PutLogFunID("AddCC"); xap_get_cc((u8 *)CC); BcdToAscii(bufcc, (BYTE *)CC,4); StringCut(bufcc,'E'); strcpy(buf,bufcc); strcat(buf,number); strcpy(number,buf); return 1; } int AddInterPrefix(char *number) { char inter_prefix[32]; char bufi[32]; char buf[32]; PutLogFunID("AddInterPrefix"); xap_get_interprefix((u8 *)inter_prefix); BcdToAscii(bufi, (BYTE *)inter_prefix,4); StringCut(bufi,'E'); strcpy(buf,number); sprintf(number,"%s%s",bufi,buf); return 1; } int AddNationalPrefix(char *number) { char national_prefix[32]; char bufn[32]; char buf[32]; PutLogFunID("AddNationalPrefix"); xap_get_nationalprefix((u8 *)national_prefix); BcdToAscii(bufn, (BYTE *)national_prefix,4); StringCut(bufn,'E'); strcpy(buf,number); sprintf(number,"%s%s",bufn,buf); return 1; } int CutUnknownPrefix(char *number) { char buf[BUFSIZE],buf1[BUFSIZE]; //char idd_prefix[4], bufi[8]; //char *offset = NULL; PutLogFunID("CutUnknownPrefix"); if(number == NULL) return 0; if(strlen(number)>MAX_ASCII_NUMBER_LEN) { pps_print_error(0, "CutUnknowPrefix src number %s is too long",number); return 0; } strcpy(buf,number); if(msisdnUnkToInt(buf,buf1)<=0) return 0; /* xap_get_interprefix(idd_prefix); BcdToAscii(bufi,idd_prefix,4); StringCut(bufi,'E'); if((offset = strstr(bufi, buf1)) != NULL) strcpy(buf, offset); else strcpy(buf, buf1); */ strcpy(buf, buf1); if(strlen(buf)>MAX_ASCII_NUMBER_LEN) { pps_print_error(0, "CutUnknowPrefix manimpulated number %s is too long",buf); return 0; } strcpy(number, buf); return 1; } int CheckWetherHPLMNUser(char *number) { char bufcc[32],buf[BUFSIZE],bufndc[32]; char CC[32],NDC[32]; int len; PutLogFunID("CheckWetherHPLMNUser"); xap_get_cc((u8 *)CC); BcdToAscii(bufcc, (BYTE *)CC,4); StringCut(bufcc,'E'); xap_get_ndc((u8 *)NDC); BcdToAscii(bufndc, (BYTE *)NDC,6); StringCut(bufndc,'E'); strcpy(buf,bufcc); strcat(buf,bufndc); len = strlen(buf); if(strncasecmp(buf,number,len)==0) return 1; return 0; } int CheckSeriveIdentification(char *serviceID,char *servicePWD,u_long srcip, int *result,char *cause) { int loop; PutLogFunID("CheckSeriveIdentification"); *result = 0; sprintf(cause,"error service ID"); for(loop=0;loopMAX_MSISDN_ALEN || strlen(called)>MAX_MSISDN_ALEN) return 0; sprintf(tmpCaller,"91%s",caller); sprintf(tmpCalled,"91%s",called); cliUptoCalled(tmpCaller,tmpCalled); if(strlen(tmpCaller)>MAX_MSISDN_ALEN) return 0; strcpy(caller,&tmpCaller[2]); return strlen(caller); } int ppsCheckMTSMSCharging(char *msisdn) { _account_info account_info; if(msisdn == NULL) return 1; if(strlen(msisdn)>=23) return 1; strcpy((char *)account_info.number, msisdn); if( !GetAccountPos(&account_info)) return 1; account_info.cos_id = GetAccountCosID(&account_info); if(ppsParam.ppsTables.cosTable[account_info.cos_id].serviceControl[0].mtSMSCharge) { if(GetAccountBalance(account_info.head, account_info.tail)>= ppsParam.ppsTables.cosTable[account_info.cos_id].serviceControl[0].mtSMSCharge) return 1; else return 0; } return 1; } int pps_get_ro_voice_quota(_state_data *shmp) { int retval = 0; if(shmp->process_info.tariff_flag == 0) return 0; if(shmp->caller_info.status != T_NORMAL) return 0; if(GetExpiration(&shmp->caller_info) < tvnow.tv_sec) return 0; retval = GetMaxCallDuration(shmp); return retval; } static int pps_update_last_ro_quota_type(_state_data *shmp, u_char new_type, u32 new_quota)// for Ro refund { if (shmp->process_info.ro_if.last_ro_quota_type == 0)// bundle { if (new_type == 0)// bundle { shmp->process_info.ro_if.last_bundle_duration += new_quota; } else { shmp->process_info.ro_if.last_cap_duration = new_quota; shmp->process_info.ro_if.last_ro_quota_type = 1; } } else { if (new_type == 0)// bundle { shmp->process_info.ro_if.last_bundle_duration = new_quota; shmp->process_info.ro_if.last_ro_quota_type = 0; } else { shmp->process_info.ro_if.last_cap_duration += new_quota; } } return 0; } // need_assigned_duration: Param IN and OUT; new_assigned_bundle, Param OUT; float pps_billing_ro_voice(_state_data *shmp, u32 *assigned_duration, u32 *new_assigned_bundle) { float charge = 0.0, balance = 0.0; _bill_tariff *bt_ptr; int discount, left_bundle, left_duration_to_assign = 0; bt_ptr = &shmp->process_info.tariff; discount = GetDiscount(tvnow.tv_sec, bt_ptr->discountID); if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) // Get left bundle { left_bundle = pps_get_account_bundle_mo_voice(shmp); balance = GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail); } else { left_bundle = pps_get_account_bundle_mt_voice(shmp); balance = GetAccountBalance(shmp->called_info.head, shmp->called_info.tail); } // allocation of the first time if (shmp->process_info.chargedTime == 0) { if (left_bundle > 0) { // allocate bunle first, and then balance if (left_bundle >= *assigned_duration)// enough bundle for first quota { *new_assigned_bundle = *assigned_duration; pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); goto out; } else { *new_assigned_bundle = left_bundle; pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); left_duration_to_assign = *assigned_duration - left_bundle;// have to allocate by balance to meet this quota *assigned_duration = left_bundle; } } else { // check if balance enough for the min charge unit if(bt_ptr->unit_time == 0 || bt_ptr->mini_unit == 0)// error param, can't allocate duratioon { *assigned_duration = 0; pps_update_last_ro_quota_type(shmp, 1, 0); goto out; } charge = (bt_ptr->mini_unit * 1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0; charge += bt_ptr->adjustment; if (charge <= balance)// have enough balance for the first basic charge { int basic_time = (bt_ptr->mini_unit * bt_ptr->unit_time) + bt_ptr->free_time; if (basic_time >= *assigned_duration)// basic time is enough for this quota { *assigned_duration = basic_time; pps_update_last_ro_quota_type(shmp, 1, 0);// basic time don't have to refund goto out; } else { left_duration_to_assign = *assigned_duration - basic_time;// have to allocate more by balance to meet this quota *assigned_duration = basic_time; pps_update_last_ro_quota_type(shmp, 1, 0);// basic time don't have to refund } } else { *assigned_duration = 0; pps_update_last_ro_quota_type(shmp, 1, 0); goto out; } } } else { if (left_bundle > 0) { // allocate bunle first, and then balance if (left_bundle >= *assigned_duration)// enough bundle for first quota { *new_assigned_bundle = *assigned_duration; pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); goto out; } else { *new_assigned_bundle = left_bundle; pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); left_duration_to_assign = *assigned_duration - left_bundle;// have to allocate by balance to meet this quota *assigned_duration = left_bundle; } } else { int units = 0; // calculate how many unit have to allocate units = (*assigned_duration + bt_ptr->unit_time -1) / bt_ptr->unit_time; // check if balance enough for the min charge unit charge = (units * 1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0; if (charge <= balance)// have enough balance for the first basic charge { *assigned_duration = units * bt_ptr->unit_time; pps_update_last_ro_quota_type(shmp, 1, *assigned_duration); goto out; } else// have no enough balance, so that assign as much unit as it could { units = balance / ((1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0); if (units > 0) { charge = (units * 1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0; *assigned_duration = units * bt_ptr->unit_time; pps_update_last_ro_quota_type(shmp, 1, *assigned_duration); } else { *assigned_duration = 0; } goto out; } } } // // have to allocate more quota by balance if (left_duration_to_assign > 0) { int units = 0; float temp_charge = 0.0; // calculate how many unit have to allocate units = (left_duration_to_assign + bt_ptr->unit_time -1) / bt_ptr->unit_time; // check if balance enough for the min charge unit temp_charge = (units * 1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0; if ((temp_charge + charge) <= balance)// have enough balance for the first basic charge { charge += temp_charge; *assigned_duration += units * bt_ptr->unit_time; pps_update_last_ro_quota_type(shmp, 1, units * bt_ptr->unit_time); goto out; } else// have no enough balance, so that assign as much unit as it could { units = (balance - charge) / ((1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0); if (units > 0) { charge += (units * 1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0; *assigned_duration += units * bt_ptr->unit_time; pps_update_last_ro_quota_type(shmp, 1, units * bt_ptr->unit_time); } goto out; } } // if(0) DebugMsg(debugmib.display.asciiOut, " %s:%d , tariff: unit=%d, %.2f+%.2f, assigned_duration=%d, , discount=%d ,charge=%.2f", __FUNCTION__, __LINE__, bt_ptr->unit_time , bt_ptr->tierRating.rating[0].base_fee, bt_ptr->tierRating.rating[0].long_distance_fee, *assigned_duration, discount, charge ); out: shmp->process_info.chargedTime ++; return charge; } float pps_billing_ro_voice_with_crm(_state_data *shmp, u32 *assigned_duration, u32 *new_assigned_bundle) { float charge = 0.0, balance = 0.0; int discount, left_bundle, left_duration_to_assign = 0; discount = shmp->process_info.rest_if.tariff_discount; left_bundle = shmp->process_info.rest_if.total_plan_value - shmp->process_info.rest_if.used_plan_value; if(shmp->process_info.serviceType == SRV_NORMAL_MO_CALL || shmp->process_info.serviceType == SRV_NORMAL_MF_CALL) { balance = GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail); } else { balance = GetAccountBalance(shmp->called_info.head, shmp->called_info.tail); } // allocation of the first time if (0)//(shmp->process_info.chargedTime == 0) { if (left_bundle > 0) { // allocate bunle first, and then balance if (left_bundle >= *assigned_duration)// enough bundle for first quota { *new_assigned_bundle = *assigned_duration; pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); goto out; } else { *new_assigned_bundle = left_bundle; pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); left_duration_to_assign = *assigned_duration - left_bundle;// have to allocate by balance to meet this quota *assigned_duration = left_bundle; } } else { // check if balance enough for the min charge unit if(shmp->process_info.rest_if.unit == 0)// error param, can't allocate duratioon { *assigned_duration = 0; pps_update_last_ro_quota_type(shmp, 1, 0); goto out; } charge = ((*assigned_duration / shmp->process_info.rest_if.unit) * 1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0; if (charge <= balance)// have enough balance for the first basic charge { pps_update_last_ro_quota_type(shmp, 1, 0);// basic time don't have to refund goto out; } else { if (balance >= shmp->process_info.rest_if.unit_charge)// last unit? { charge = balance; *assigned_duration = shmp->process_info.rest_if.unit; pps_update_last_ro_quota_type(shmp, 1, 0); goto out; } else { *assigned_duration = 0; pps_update_last_ro_quota_type(shmp, 1, 0); goto out; } } } } else { if (left_bundle > 0) { // allocate bunle first, and then balance if (left_bundle >= *assigned_duration)// enough bundle for first quota { *new_assigned_bundle = *assigned_duration; pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); goto out; } else { *new_assigned_bundle = left_bundle; pps_update_last_ro_quota_type(shmp, 0, *new_assigned_bundle); left_duration_to_assign = *assigned_duration - left_bundle;// have to allocate by balance to meet this quota *assigned_duration = left_bundle; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) DebugMsg(debugmib.display.asciiOut, " %s:%d, left bundle[%d], assigned=[%d], need assigned by balance=[%d]", __FUNCTION__, __LINE__, left_bundle, *assigned_duration, left_duration_to_assign ); } else { int units = 0; // calculate how many unit have to allocate units = (*assigned_duration + shmp->process_info.rest_if.unit -1) / shmp->process_info.rest_if.unit; // check if balance enough for the min charge unit charge = (units * 1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0; if (charge <= balance)// have enough balance for the first basic charge { *assigned_duration = units * shmp->process_info.rest_if.unit; pps_update_last_ro_quota_type(shmp, 1, *assigned_duration); goto out; } else// have no enough balance, so that assign as much unit as it could { units = balance / ((1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0); if (units > 0) { charge = (units * 1.0 * (shmp->process_info.rest_if.unit_charge)) * discount / 100.0; *assigned_duration = units * shmp->process_info.rest_if.unit; pps_update_last_ro_quota_type(shmp, 1, *assigned_duration); } else { *assigned_duration = 0; charge = 0.0; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) DebugMsg(debugmib.display.asciiOut, " %s:%d, no enough balance: units[%d], assigned=[%d], balance=%.2f, charge=%.2f", __FUNCTION__, __LINE__, units, *assigned_duration, balance, charge ); goto out; } } } // // have to allocate more quota by balance if (left_duration_to_assign > 0) { int units = 0; float temp_charge = 0.0; // calculate how many unit have to allocate units = (left_duration_to_assign + shmp->process_info.rest_if.unit -1) / shmp->process_info.rest_if.unit; // check if balance enough for the min charge unit temp_charge = (units * 1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0; if ((temp_charge + charge) <= balance)// have enough balance for the first basic charge { charge += temp_charge; *assigned_duration += units * shmp->process_info.rest_if.unit; pps_update_last_ro_quota_type(shmp, 1, units * shmp->process_info.rest_if.unit); goto out; } else// have no enough balance, so that assign as much unit as it could { units = (balance - charge) / ((1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0); if (units > 0) { charge += (units * 1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0; *assigned_duration += units * shmp->process_info.rest_if.unit; pps_update_last_ro_quota_type(shmp, 1, units * shmp->process_info.rest_if.unit); } goto out; } } // out: if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || shmp->process_info.logMsisdn) DebugMsg(debugmib.display.asciiOut, " %s:%d, tariff: unit=%d*%.2f, assigned/bundle/cap=[%d/%d/%d], discount=%d, charge=%.2f", __FUNCTION__, __LINE__, shmp->process_info.rest_if.unit, shmp->process_info.rest_if.unit_charge, *assigned_duration, *new_assigned_bundle, left_duration_to_assign, discount, charge ); shmp->process_info.chargedTime ++; return charge; } float pps_refund_ro_voice_with_crm(_state_data *shmp, u32 refund_duration, u32 *refund_bundle) { float charge = 0.0; u32 bundle_duration = 0, cap_duration = 0; int discount; discount = shmp->process_info.rest_if.tariff_discount; if (shmp->process_info.ro_if.last_ro_quota_type == 0)// bundle { if (refund_duration <= shmp->process_info.ro_if.last_bundle_duration) { // all refund to bundle bundle_duration = refund_duration; } else { bundle_duration = shmp->process_info.ro_if.last_bundle_duration; cap_duration = refund_duration - bundle_duration; } } else { if (refund_duration <= shmp->process_info.ro_if.last_cap_duration) { // all refund to balance cap_duration = refund_duration; } else { cap_duration = shmp->process_info.ro_if.last_cap_duration; bundle_duration = refund_duration - cap_duration; } } *refund_bundle = bundle_duration; if ((shmp->process_info.rest_if.unit > 0) && (cap_duration >= shmp->process_info.rest_if.unit)) { int units = 0; units = cap_duration / shmp->process_info.rest_if.unit; charge = (units * 1.0 * ( shmp->process_info.rest_if.unit_charge)) * discount / 100.0; } return charge; } float pps_refund_ro_voice(_state_data *shmp, u32 refund_duration, u32 *refund_bundle) { float charge = 0.0; _bill_tariff *bt_ptr; u32 bundle_duration = 0, cap_duration = 0; int discount; bt_ptr = &shmp->process_info.tariff; discount = GetDiscount(tvnow.tv_sec, bt_ptr->discountID); if (shmp->process_info.ro_if.last_ro_quota_type == 0)// bundle { if (refund_duration <= shmp->process_info.ro_if.last_bundle_duration) { // all refund to bundle bundle_duration = refund_duration; } else { bundle_duration = shmp->process_info.ro_if.last_bundle_duration; cap_duration = refund_duration - bundle_duration; } } else { if (refund_duration <= shmp->process_info.ro_if.last_cap_duration) { // all refund to balance cap_duration = refund_duration; } else { cap_duration = shmp->process_info.ro_if.last_cap_duration; bundle_duration = refund_duration - cap_duration; } } *refund_bundle = bundle_duration; if (bt_ptr->unit_time == 0) { bt_ptr->unit_time = 60; } if (cap_duration >= bt_ptr->unit_time) { int units = 0; units = cap_duration / bt_ptr->unit_time; charge = (units * 1.0 * ( bt_ptr->tierRating.rating[0].base_fee + bt_ptr->tierRating.rating[0].long_distance_fee)) * discount / 100.0; } return charge; } /*-----------CRM related functions --------------------------------*/ int pps_update_user_info_for_crm_create_account(_prepaid_info *user_ptr, int customer_id, int account_id, int product_id, int plan_id, int balance, int expiry_day, int rent_charge, int birthday, int cug_id) { if(user_ptr == NULL) return 0; #ifdef OCS_WITH_CRM user_ptr->balance = balance; user_ptr->mo_expiration_date = user_ptr->mt_expiration_date = expiry_day; user_ptr->crm_info.customer_id = customer_id; user_ptr->crm_info.account_id = account_id; user_ptr->crm_info.product_id = product_id; user_ptr->crm_info.base_plan_id = plan_id; user_ptr->crm_info.rent_charge = rent_charge; user_ptr->crm_info.birthday = birthday; user_ptr->cug_id = cug_id; user_ptr->status = T_NORMAL; #endif return 1; }