#include #include #include "../include/ppsm.h" #include "../include/ramdata.h" #include "../include/param.h" #include "../include/mfunc.h" #include "../include/plat_inc.h" #include "../include/mfunc.h" #include "../include/precard.h" #include "../include/report.h" #include "../include/restapi.h" /*----------------------------------------*/ extern _ram_data *ramshm_ptr; extern _state_machine *smshm_ptr; extern int logMsgFlag; extern char logMsisdn[]; extern struct timeval tvnow; /*----------------------------------------*/ /*----------------------------------------*/ extern int smppEncodeSM(); extern int DebugMsg(); extern int pps_send_map_opr(); #ifdef OCS_USE_REDIS_DB extern int RedisGetTariffInfo(u_short portid, char *service_nbr, int service_type, char *called_num); extern int RedisUpdateUsedBundle(char *service_nbr, int service_type, int rr_id, unsigned long long used_bundle_this_time); #endif //extern int map_get_comdata_struct(); //extern int map_com_stof(); extern int pps_send_map_openrsp(); extern int ppsBcdToAsciiR(); extern int GetAccountPos(); extern int GetAccountCosID(); extern int GetAccountCUG(); extern int AccountLatchFlagCheck(); extern int CheckWetherValidRechargeCard(); extern int RechargeRequestProc(); extern int pps_send_map_open(); extern void StringCut(char *str, int c); extern int SendAccountInfoBySMPP(); extern int ppsAsciiToBcdR(); extern int transferAccountUSSDProc(u_short portid); extern int ppsSendUSSDStatistics(_state_data *shmp); extern void pps_send_update_subs_status_to_crm(_prepaid_info *user_ptr, int update_flag); extern PPSParamStruct ppsParam; /*----------------------------------------*/ int GetUSSDOperationType(char *ussd_data) { //char ussd_format[128]; return 1; } int ppsGetUssdParameter(char *ussd_data, char *ussd_sc, char *ussd_param, char *ussd_param1) { int i, len, index=0, type=0; len = strlen(ussd_data); ussd_param[0] = '\0'; /* clear ussd parameter */ ussd_param1[0]= '\0'; for(i=0;i0) { type++; index = 0; } } } return 1; } int GetUSSDRequest(u_short portid, char *ussd_data) { int retval = 0,len; u_char data_flow[256]; MapOprSrv_struct opr_srv; struct MapPUSSR_Arg *pussr_arg; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) { return retval; } if((data_flow[9] != ProcUnstrctSSReq) || data_flow[1]<14) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d ,did: %d, wait PSSDR but %d received\33[0m", portid,shmp->context_info.map_did,data_flow[9]); } pps_send_map_close(portid); return -1; } if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\nportid: %d ,did: %d, Get Map opr,type:<%d>, PUSSR ", portid,shmp->context_info.map_did, data_flow[9]); pps_debug_map_msg(data_flow,0); } opr_srv.version = shmp->context_info.map_acn_ver; opr_srv.message_type = data_flow[9]; opr_srv.message_flag = data_flow[10]; opr_srv.port_id = portid; opr_srv.dialogue_id = shmp->context_info.map_did; if(extract_mapparam(&opr_srv, data_flow[9], data_flow[10], data_flow[14]*256+data_flow[15], &data_flow[16])<=0) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31mportid: %d ,did: %d, decode PUSSR failed \33[0m", portid,shmp->context_info.map_did); } ppsSendUSSDStatistics(shmp); return -1; } shmp->context_info.invoke_id = data_flow[11]; //opr_srv.invoke_id; pussr_arg = &opr_srv.msg_list.pussr_arg; if(pussr_arg->param_flag != 0x01) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31mportid: %d ,did: %d, decode PUSSR failed \33[0m", portid,shmp->context_info.map_did); } ppsSendUSSDStatistics(shmp); return -1; } len = pussr_arg->ussd_arg.ussd_string.string_len; if(len > 24) len = 24; switch(pussr_arg->ussd_arg.ussd_scheme & 0x0f) { case 0x00: case 0x0f: /* 7bit */ smppDecodeSM((char *)pussr_arg->ussd_arg.ussd_string.ussd_data, ussd_data, len); break; case 0x04: /* 8bit */ default: memcpy(ussd_data, pussr_arg->ussd_arg.ussd_string.ussd_data, len); break; } if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\nportid: %d ,did: %d, USSD data: \r\n\%s ", portid,shmp->context_info.map_did, ussd_data); } return 1; } int SendUSSDRequest(u_short portid, char *ussd_info) { int len; u_char buf[256]; MapOprSrv_struct opr_srv; MapOprData_struct opr_data; struct MapUSSR_Arg *ussr_arg; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); shmp->context_info.map_iid = map_get_invokeid(shmp->context_info.map_did); opr_srv.invoke_id = shmp->context_info.map_iid; opr_srv.version = shmp->context_info.map_acn_ver; opr_srv.message_type = UnstrctSSReq; opr_srv.message_flag = MAP_REQUEST; opr_srv.port_id = portid; opr_srv.dialogue_id = shmp->context_info.map_did; ussr_arg = &opr_srv.msg_list.ussr_arg; ussr_arg->param_flag = 0x01; ussr_arg->ussd_arg.param_flag = 0x03; // ussr_arg->ussd_arg.ussd_scheme = 0x04; /* 8bit */ ussr_arg->ussd_arg.ussd_scheme = 0x0f; /* 7bit */ len = smppEncodeSM(ussd_info,buf); ussr_arg->ussd_arg.ussd_string.string_len = len;//strlen(ussd_info); memcpy(ussr_arg->ussd_arg.ussd_string.ussd_data, buf, ussr_arg->ussd_arg.ussd_string.string_len); opr_data.port_id = portid; opr_data.dialogue_id = opr_srv.dialogue_id; opr_data.invoke_id = opr_srv.invoke_id; opr_data.message_type = opr_srv.message_type; opr_data.message_flag = opr_srv.message_flag; opr_data.param_flag = 0x1f; len = build_mapparam(&opr_srv,opr_data.param); if(len<=0 || len>MAX_MAPPOPR_LEN) { return 0; } opr_data.param_len = len; opr_data.param_flag |= 0x20; if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "portid: %d ,did: %d, Send Map USSD_Req. @ %ld.%ld", portid,shmp->context_info.map_did, tvnow.tv_sec,tvnow.tv_usec); } pps_send_map_opr(&opr_data, 1); return 1; } int SendUSSDNotify(u_short portid, char *ussd_info) { int len; u_char buf[256]; MapOprSrv_struct opr_srv; MapOprData_struct opr_data; struct MapUSSN_Arg *ussn_arg; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); shmp->context_info.map_iid = map_get_invokeid(shmp->context_info.map_did); opr_srv.invoke_id = shmp->context_info.map_iid; opr_srv.version = shmp->context_info.map_acn_ver; opr_srv.message_type = UnstrctSSNoti; opr_srv.message_flag = MAP_REQUEST; opr_srv.port_id = portid; opr_srv.dialogue_id = shmp->context_info.map_did; ussn_arg = &opr_srv.msg_list.ussn_arg; ussn_arg->param_flag = 0x01; ussn_arg->ussd_arg.param_flag = 0x03; //ussn_arg->ussd_arg.ussd_scheme = 0x04; /* 8bit */ ussn_arg->ussd_arg.ussd_scheme = 0x0f; /* 7bit */ len = smppEncodeSM(ussd_info,buf); ussn_arg->ussd_arg.ussd_string.string_len = len; //strlen(ussd_info); memcpy(ussn_arg->ussd_arg.ussd_string.ussd_data, buf, ussn_arg->ussd_arg.ussd_string.string_len); opr_data.port_id = portid; opr_data.dialogue_id = opr_srv.dialogue_id; opr_data.invoke_id = opr_srv.invoke_id; opr_data.message_type = opr_srv.message_type; opr_data.message_flag = opr_srv.message_flag; opr_data.param_flag = 0x1f; len = build_mapparam(&opr_srv,opr_data.param); if(len<=0 || len>MAX_MAPPOPR_LEN) { return 0; } opr_data.param_len = len; opr_data.param_flag |= 0x20; if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "portid: %d ,did: %d, Send Map USSD_Notify. @ %ld.%ld", portid,shmp->context_info.map_did, tvnow.tv_sec,tvnow.tv_usec); } pps_send_map_opr(&opr_data, 1); return 1; } int SendPSSRResponse(u_short portid) { int len; u_char buf[256]; MapOprSrv_struct opr_srv; MapOprData_struct opr_data; struct MapPUSSR_Res *pussr_res; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); opr_srv.invoke_id = shmp->context_info.invoke_id; opr_srv.version = shmp->context_info.map_acn_ver; opr_srv.message_type = ProcUnstrctSSReq; opr_srv.message_flag = MAP_RESPONSE; opr_srv.port_id = portid; opr_srv.dialogue_id = shmp->context_info.map_did; pussr_res = &opr_srv.msg_list.pussr_res; pussr_res->param_flag = 0x01; pussr_res->ussd_res.param_flag = 0x03; pussr_res->ussd_res.ussd_scheme = 0x0f; /* 7bit */ switch(shmp->process_info.u_error) { case CAP_ERR_MISSING_CUSTOMER_RECORD: len = smppEncodeSM(getSmsSentenceNative(0,SMS_NOT_REGISTER_PREPAID_USER),buf); break; case _PPS_ERR_SERVICE_NOT_APPLIED: len = smppEncodeSM(getSmsSentenceNative(0,SMS_SERVICE_NOT_APPLIED),buf); break; default: len = smppEncodeSM(getSmsSentenceNative(0,SMS_USSD_COMPLETED),buf); break; } pussr_res->ussd_res.ussd_string.string_len = len;//strlen(ussd_info); memcpy(pussr_res->ussd_res.ussd_string.ussd_data, buf, pussr_res->ussd_res.ussd_string.string_len); opr_data.port_id = portid; opr_data.dialogue_id = opr_srv.dialogue_id; opr_data.invoke_id = opr_srv.invoke_id; opr_data.message_type = opr_srv.message_type; opr_data.message_flag = opr_srv.message_flag; opr_data.param_flag = 0x1f; len = build_mapparam(&opr_srv,opr_data.param); if(len<=0 || len>MAX_MAPPOPR_LEN) { return 0; } opr_data.param_len = len; opr_data.param_flag |= 0x20; if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "portid: %d ,did: %d, Send Map PUSSR_Ack. @ %ld.%ld", portid,shmp->context_info.map_did, tvnow.tv_sec,tvnow.tv_usec); } pps_send_map_opr(&opr_data, 0); return 1; } int SendPSSREnd(u_short portid,char *ussd_info) { int len; u_char buf[256]; MapOprSrv_struct opr_srv; MapOprData_struct opr_data; struct MapPUSSR_Res *pussr_res; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); opr_srv.invoke_id = shmp->context_info.invoke_id; opr_srv.version = shmp->context_info.map_acn_ver; opr_srv.message_type = ProcUnstrctSSReq; opr_srv.message_flag = MAP_RESPONSE; opr_srv.port_id = portid; opr_srv.dialogue_id = shmp->context_info.map_did; pussr_res = &opr_srv.msg_list.pussr_res; pussr_res->param_flag = 0x01; pussr_res->ussd_res.param_flag = 0x03; pussr_res->ussd_res.ussd_scheme = 0x0f; /* 7bit */ len = smppEncodeSM(ussd_info,buf); pussr_res->ussd_res.ussd_string.string_len = len;//strlen(ussd_info); memcpy(pussr_res->ussd_res.ussd_string.ussd_data, buf, pussr_res->ussd_res.ussd_string.string_len); opr_data.port_id = portid; opr_data.dialogue_id = opr_srv.dialogue_id; opr_data.invoke_id = opr_srv.invoke_id; opr_data.message_type = opr_srv.message_type; opr_data.message_flag = opr_srv.message_flag; opr_data.param_flag = 0x1f; len = build_mapparam(&opr_srv,opr_data.param); if(len<=0 || len>MAX_MAPPOPR_LEN) { return 0; } opr_data.param_len = len; opr_data.param_flag |= 0x20; if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "portid: %d ,did: %d, Send Map PUSSR_Ack. @ %ld.%ld", portid,shmp->context_info.map_did, tvnow.tv_sec,tvnow.tv_usec); } pps_send_map_opr(&opr_data, 0); return 1; } int SendUSSDTellMeNumberInfo(u_short portid) { char ussd_info[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); sprintf(ussd_info, "%s %s", getSmsSentenceNative(0,SMS_TELL_ME_NUMBER), shmp->caller_info.number); if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[36m portid: %d ,did: %d, USSD Tell Me Number notify\n %s\33[0m", portid,shmp->context_info.map_did, ussd_info); } SendPSSREnd(portid,ussd_info); return 1; } int GetAccountRestInfo(u_short portid, char *prompt_info) { _state_data *shmp = (_state_data *) smshm_ptr->state_data; long balance, promotion=0; char expire_date[64]={0},promotion_expire_date[64]={0}; char buf[2*MAX_SMS_LEN]="",buf2[4*MAX_SMS_LEN]=""; int len,totalLen, tmp_len=0; PutLogFunID("GetAccountRestInfo"); if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); memset(buf,0,MAX_SMS_LEN*2); memset(buf2,0,MAX_SMS_LEN*4); AsciiTime(expire_date,shmp->process_info.rest_if.mo_expiry_date); balance = shmp->process_info.rest_if.balance; /******************** balance **************************************/ #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ if(strstr(getSmsSentenceNative(0,SMS_ACCOUNT_BALANCE), "%s") == NULL) { sprintf(buf,"%s",getSmsSentenceNative(0,SMS_ACCOUNT_BALANCE)); } else { sprintf(buf, (char *)getSmsSentenceNative(0, SMS_ACCOUNT_BALANCE), (char *)shmp->caller_info.number); } #else sprintf(buf,"Your balance for %s is ", (char *)shmp->caller_info.number); #endif len = strlen(buf); strcpy(buf2,buf); totalLen = len; memset(buf,0,MAX_SMS_LEN*2); len = fillMoneyAndDate(balance,expire_date,0,0, (u_char *)buf); strcat(buf2,buf); totalLen += len; tmp_len = totalLen; /******************** balance **************************************/ /******************** promotion **************************************/ if(promotion > 0) { memset(buf,0,MAX_SMS_LEN*2); sprintf(buf,"%s",getSmsSentenceNative(0,SMS_ACCOUNT_PROMOTION)); len = strlen(buf); strcat(buf2,buf); totalLen += len; memset(buf,0,MAX_SMS_LEN*2); len = fillMoneyAndDate(promotion,promotion_expire_date,0,0, (u_char *)buf); strcat(buf2,buf); totalLen += len; } memcpy(prompt_info,buf2,240); prompt_info[240]=0; if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[36m portid: %d ,did: %d, USSD inquiry notify\n %s\33[0m", portid,shmp->context_info.map_did, prompt_info); } /******************** promotion **************************************/ return tmp_len; } int SendUSSDInqiuryInfo(u_short portid) { char ussd_info[256]; int len; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); len = GetAccountPromptInfo(&shmp->caller_info,ussd_info)%256; ussd_info[len] = 0; if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[36m portid: %d ,did: %d, USSD inquiry notify\n %s\33[0m", portid,shmp->context_info.map_did, ussd_info); } //SendUSSDNotify(portid,ussd_info); SendPSSREnd(portid,ussd_info); return 1; } int SendLowBalanceUSSDNotify(u_short portid) { SendUSSDNotify(portid, (char *)getSmsSentenceNative(0,SMS_LOW_BALANCE_NOTIFY)); return 1; } int SendUSSDRechargeRequest(u_short portid) { SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_RECHARGE_INPUT_PIN)); return 1; } int SendUSSDRechargeRequestAgain(u_short portid) { SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_RECHARGE_INPUT_PIN_AGAIN)); return 1; } int UssdInquiryProcess(u_short portid) { int caller_status; //int instance; _state_data *shmp = (_state_data *) smshm_ptr->state_data; COSTable *cosTableItem; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); if(pps_get_adaptor_flag()) { shmp->process_info.sub_state = S_MAP_REST_QUERY; shmp->process_info.sub_state_2 = 0; shmp->process_info.rest_if.rest_oc = 0; shmp->process_info.rest_if.rest_src = 0; return 0; } shmp->process_info.sub_state = S_MAP_WAIT_USSN_ACK; shmp->process_info.serviceKey = 1; shmp->process_info.sub_state = S_MAP_WAIT_USSN_ACK; caller_status = GetAccountStatus(&shmp->caller_info); cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; if(caller_status == T_FRESH) { if(cosTableItem->accountValidity[0].activiationByInquiryIs) { int instance; UpdateAccountStatus(shmp->caller_info.head, shmp->caller_info.tail, T_NORMAL); UpdateAccountFirstUsedDate( shmp->caller_info.head, shmp->caller_info.tail); UpdateExpirationFirstInquiry( &shmp->caller_info, cosTableItem->accountValidity[0].validiDaysActivatedByInquiringAccountWithZeroBalance); instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; SendAccountRealSync(instance,0.0,0.0,OMC_OCODE_EDIT); smppSendActivicationInfo(&shmp->caller_info, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number); caller_status = T_NORMAL; } } if(caller_status == T_NORMAL) { if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenInquiry) { SendAccountInfoBySMPP(&shmp->caller_info, ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number); } } SendUSSDInqiuryInfo(portid); return 1; } int SendUSSDRechargeSuccessInfo(u_short portid) { char ussd_info[256],account_info[250]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); GetAccountPromptInfo(&shmp->caller_info,account_info); sprintf(ussd_info,"%s %s",getSmsSentenceNative(0,SMS_GPRS_RECHARGE_SUCCESS),account_info); if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[36m portid: %d ,did: %d, USSD recharge notify\n %s\33[0m ", portid,shmp->context_info.map_did, ussd_info); } //SendUSSDNotify(portid,ussd_info); SendPSSREnd(portid,ussd_info); return 1; } int SendUSSDFavortieInfo(u_short portid, int type) { char ussd_info[256], buf[128]; int i, head, tail, cos_id, plan_id, free_sms, free_call_duration; int send_request_flag = 0, retval = 1,counter=0; _prepaid_info *user_ptr=NULL; CosFriendFamilyControl *friendFamilyControl; _state_data *shmp = (_state_data *) smshm_ptr->state_data; char *buf_ptr[8],tmp_buf[8][32]; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); head = shmp->caller_info.head; tail = shmp->caller_info.tail; user_ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; for(i=0;i<8;i++) buf_ptr[i] = tmp_buf[i]; switch(type) { case 0: /* not register F&F service */ sprintf(ussd_info,"%s",getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_NOT_REGISTERED) ); break; case 1: /* not F&F plan user */ sprintf(tmp_buf[0], "%d", user_ptr->favorite_numbers); counter = 1; for(i=0;ifavorite_number[i][MAX_MSISDN_BLEN-1]>3) { sprintf(tmp_buf[counter], "#%d: ", i); MsisdnToAscii(buf, user_ptr->favorite_number[i]); strcat(tmp_buf[counter++], buf); } } if(counter>2) { sprintf(ussd_info,"%s ...", ppsParseSentence((char *)getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_NOT_PLAN), 2, buf_ptr)); sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_QUERY); } else { sprintf(ussd_info,"%s", ppsParseSentence((char *)getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_NOT_PLAN), counter, buf_ptr)); } break; case 2: /* F&F plan service is suspened */ cos_id = user_ptr->cos_id; plan_id = user_ptr->favorite_plan_id; friendFamilyControl = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; if(friendFamilyControl->friendFamilyPlan[plan_id-1].rentCharge > GetAccountBalance(head, tail)) { sprintf(ussd_info, "%s", getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_SUSPENDT)); } else { sprintf(ussd_info, "%s", getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_SUSPEND_REAC)); send_request_flag = 1; retval = 0; } break; case 3: /* F&F plan service is OK */ cos_id = user_ptr->cos_id; plan_id = user_ptr->favorite_plan_id-1; friendFamilyControl = &ppsParam.ppsTables.cosTable[cos_id].friendFamilyControl[0]; free_sms = friendFamilyControl->friendFamilyPlan[plan_id].freeSMS; free_call_duration = friendFamilyControl->friendFamilyPlan[plan_id].freeCallDuration*60; sprintf(tmp_buf[0], "%d", user_ptr->favorite_numbers); if(free_call_duration>0) sprintf(tmp_buf[1], "%lu", user_ptr->free_favorite_call>free_call_duration ? 0: ((free_call_duration- user_ptr->free_favorite_call)/60)); else sprintf(tmp_buf[1], "%s", getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_NO_LIMIT)); if(free_sms >0) sprintf(tmp_buf[2], "%lu", user_ptr->free_favorite_sms> free_sms ? 0: free_sms-user_ptr->free_favorite_sms); else sprintf(tmp_buf[2], "%s", getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY_NO_LIMIT)); sprintf(ussd_info, "%s ", ppsParseSentence((char *)getSmsSentenceNative(0,SMS_FRIEND_FAMILY_QUERY), 3, buf_ptr)); /* for(i=0;ifavorite_number[i][MAX_MSISDN_BLEN-1]>3) { sprintf(buf, "#%d: ", i); strcat(ussd_info, buf); MsisdnToAscii(buf, user_ptr->favorite_number[i]); strcat(ussd_info, buf); } } */ default: break; } // GetAccountPromptInfo(&shmp->caller_info,account_info); // sprintf(ussd_info,"%s,%s",getSmsSentenceNative(0,SMS_GPRS_RECHARGE_SUCCESS),account_info); if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[36m portid: %d ,did: %d, USSD Friends & Family info:\n %s\33[0m ", portid,shmp->context_info.map_did, ussd_info); } if(send_request_flag == 0) SendPSSREnd(portid,ussd_info); else SendUSSDRequest(portid, ussd_info); return retval; } int reactivateFaviroteSericeUssdProc(u_short portid) { int retval = 0,len, head ,tail,charge=0; u_char data_flow[256]; char ussd_data[256],ussd_info[256]; MapOprSrv_struct opr_srv; CosFriendFamilyControl *friendFamilyControl; //struct MapPUSSR_Arg *pussr_arg; struct MapUSSR_Res *ussr_ack; _prepaid_info *user_ptr=NULL; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return 1; } shmp += portid; if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) { return retval; } if((data_flow[9] != UnstrctSSReq) || data_flow[1]<14) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d ,did: %d, wait USSDR_ACK but %d received\33[0m", portid,shmp->context_info.map_did,data_flow[9]); } ppsSendUSSDStatistics(shmp); return 1; } if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\nportid: %d ,did: %d, Get Map opr,type:<%d>, USSR ", portid,shmp->context_info.map_did, data_flow[9]); pps_debug_map_msg(data_flow,0); } opr_srv.version = shmp->context_info.map_acn_ver; opr_srv.message_type = data_flow[9]; opr_srv.message_flag = data_flow[10]; opr_srv.port_id = portid; opr_srv.dialogue_id = shmp->context_info.map_did; if(extract_mapparam(&opr_srv, data_flow[9], data_flow[10], data_flow[14]*256+data_flow[15], &data_flow[16])<=0) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31mportid: %d ,did: %d, decode USSR_ACK failed \33[0m", portid,shmp->context_info.map_did); } ppsSendUSSDStatistics(shmp); return -1; } ussr_ack = &opr_srv.msg_list.ussr_res; if(ussr_ack->param_flag != 0x01) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31mportid: %d ,did: %d, USSR error received \33[0m", portid,shmp->context_info.map_did); } return -1; } retval = 1; head = shmp->caller_info.head; tail = shmp->caller_info.tail; user_ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; switch(ussr_ack->ussd_res.ussd_scheme & 0x0f) { case 0x00: case 0x0f: /* 7bit */ smppDecodeSM((char *)ussr_ack->ussd_res.ussd_string.ussd_data, ussd_data, ussr_ack->ussd_res.ussd_string.string_len); break; case 0x04: /* 8bit */ default: memcpy(ussd_data, ussr_ack->ussd_res.ussd_string.ussd_data, ussr_ack->ussd_res.ussd_string.string_len); break; } if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\nportid: %d ,did: %d, USSD data: %s", portid,shmp->context_info.map_did, ussd_data); } len = strlen(ussd_data); if(len>16) { ussd_data[16] = 0; len = 16; } if(ussd_data[0] == '1') /* check response here */ { } user_ptr->favorite_plan_state = 0; user_ptr->free_favorite_call = 0; user_ptr->free_favorite_sms = 0; user_ptr->fav_change_counter = 0; friendFamilyControl = &ppsParam.ppsTables.cosTable[user_ptr->cos_id].friendFamilyControl[0]; charge = friendFamilyControl->friendFamilyPlan[user_ptr->favorite_plan_id-1].rentCharge; shmp->caller_info.charge = charge; user_ptr->balance = user_ptr->balance - charge; //UpdateAccountBalance( head, tail, -charge ); // SendOperatorRechargeCDR(head,tail, -charge); SendPPSGeneralCDR(head, tail, -charge, CT_FF_ACTIVATION); SendAccountRealSync(head*UNIT_STORE_ACCOUNT+tail,-charge,0,2); if(ppsParam.ppsTables.cosTable[user_ptr->cos_id].smsNotificationInquiry[0].smsNotificationWhenFriendFamilyServiceReg) sendPPSNotificationMessage(head, tail, SMS_FRIEND_FAMILY_REG); sprintf(ussd_info, "%s", getSmsSentenceNative(0,SMS_FRIEND_FAMILY_SERIVCE_REACTIVATE)); SendPSSREnd(portid,ussd_info); //SendUSSDNotify(portid,ussd_info); return retval; } int favoriteNumberUssdProc(u_short portid) { int retval = SERVICE_KEEP_STATE; int head,tail; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _prepaid_info *user_ptr=NULL; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); switch(shmp->process_info.sub_state_2) { case 0: head = shmp->caller_info.head; tail = shmp->caller_info.tail; user_ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; if(user_ptr->favorite_plan_id<1 && user_ptr->favorite_numbers<=0) { shmp->process_info.sub_state_2 = 1; } else { if(user_ptr->favorite_plan_id<1) { shmp->process_info.sub_state_2 = 2; } else { if(user_ptr->favorite_plan_state>0) { shmp->process_info.sub_state_2 = 3; } else { shmp->process_info.sub_state_2 = 4; } } } break; case 1: SendUSSDFavortieInfo(portid,0);/* not register F&F service */ return SERVICE_EXIT_PPS; break; case 2: SendUSSDFavortieInfo(portid, 1); /* not F&F plan user */ return SERVICE_EXIT_PPS; break; case 3: if( SendUSSDFavortieInfo(portid, 2)== 0) /* F&F plan service is suspended */ shmp->process_info.sub_state_2 = 5; else return SERVICE_EXIT_PPS; break; case 4: SendUSSDFavortieInfo(portid, 3); /* F&F plan service is OK */ return SERVICE_EXIT_PPS; break; case 5: if(reactivateFaviroteSericeUssdProc(portid)) { return SERVICE_EXIT_PPS; //SERVICE_RETURN_TO_PARENT; } break; default: return SERVICE_EXIT_PPS; break; } return retval; } static int pps_send_rest_msg(u8 *msg_buf, int len) { message_list iptr_msg; iptr_msg.msgSrcPort = REST_PROXY_PORT; iptr_msg.msgDstPort = 4900; iptr_msg.msgDstIP = GetLocalIP(); iptr_msg.msgLength = len; memcpy(iptr_msg.msgContent, msg_buf, len); iptrPutMessage(iptr_msg); return 0; } int pps_send_rest_query_req(u_short portid) { int len = 0; u_char data_flow[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _rest_msg_s rest_msg; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); rest_msg.msg_type = REST_QUERY; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = portid; strcpy(rest_msg.msg.query.msisdn, (char *)shmp->caller_info.number); len = encode_rest_query(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); return 1; } extern _prepaid_info *getPrepaidInfo(_account_info *account); static int pps_handle_send_authcode_req(_rest_msg_s *rest_req) { _rest_send_authcode_req *pReq = &rest_req->msg.send_authcode_req; _rest_msg_s rest_rsp; _rest_send_authcode_rsp *pRsp = &rest_rsp.msg.send_authcode_rsp; u8 msg_buf[256]; int len; PutLogFunID("pps_handle_send_authcode_req"); // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, pps_handle_send_authcode_req(), msisdn[%s], sms[%s]", \ tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn, pReq->sms_content); } // check log msisdn int flag_log_msisdn = 0; _account_info user_info; strcpy((char *)user_info.number, pReq->msisdn); if(logMsgFlag & 0x08) { if(strstr((char *)user_info.number, logMsisdn)) { flag_log_msisdn = 1; } } int err_code = ERR_REST_SUCCESS; if ((strlen(pReq->msisdn) == 0) || (strlen(pReq->sms_content) == 0)) { if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "pps_handle_send_authcode_req(), invalid param"); } err_code = ERR_REST_INVALID_PARAMETER_VALUE; goto out; } // get user info GetAccountPos(&user_info); int status = GetAccountStatus(&user_info); if ((status != T_NORMAL) && (status != T_SUSPEND)) { if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "pps_handle_send_authcode_req(), msisdn[%s], err status[%d]", \ pReq->msisdn, status); } err_code = ERR_REST_USER_UNKNOWN; } else { // send authcode smppSendMOSM((char *)user_info.number, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, \ (u_char *)pReq->sms_content, strlen(pReq->sms_content), 0); } out: // send response msg================ rest_rsp.msg_type = REST_SEND_AUTHCODE_RSP; rest_rsp.header.dst_ref = rest_req->header.src_ref; rest_rsp.header.src_ref = rest_req->header.dst_ref; pRsp->error_code = err_code; if (err_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; } else { pRsp->result = RES_SUCCEED; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "reply REST_TRANSFER_RSP, result[%d]", err_code); } len = encode_rest_send_authcode_rsp(&rest_rsp, msg_buf); pps_send_rest_msg(msg_buf, len); // return 0; } static int pps_handle_query_userdata_req(_rest_msg_s *rest_req) { _rest_query_user_data_req *pReq = &rest_req->msg.query_user_data_req; PutLogFunID("pps_handle_query_userdata_req"); // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, pps_handle_query_userdata_req(), msisdn[%s]", \ tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn); } int flag_log_msisdn = 0; _account_info user_info; strcpy((char *)user_info.number, pReq->msisdn); if(logMsgFlag & 0x08) { if(strstr((char *)user_info.number, logMsisdn)) { flag_log_msisdn = 1; } } int err_code = ERR_REST_SUCCESS; _prepaid_info *pUsrInfo = NULL; if ((GetAccountPos(&user_info) == FALSE) || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) { if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "pps_handle_query_userdata_req(), msisdn[%s], not found", \ pReq->msisdn); } err_code = ERR_REST_USER_UNKNOWN;// not found } // set message _rest_msg_s rest_rsp; _rest_query_user_data_rsp *pRsp = &rest_rsp.msg.query_user_data_rsp; memset(pRsp, 0, sizeof(_rest_query_user_data_rsp)); memcpy(pRsp->msisdn, pReq->msisdn, 24); if (pUsrInfo != NULL) { //usrGroupName int cos_id = GetAccountCosID(&user_info); strcpy(pRsp->usrGrpName, (char *)ppsParam.ppsTables.cosTable[cos_id].title); pRsp->status = pUsrInfo->status; pRsp->balance = (u32)pUsrInfo->balance; pRsp->mo_expiry = pUsrInfo->mo_expiration_date; pRsp->remain_mo_voc_min = pUsrInfo->bundle_info.mo_voice/60; pRsp->remain_mt_voc_min = pUsrInfo->bundle_info.mt_voice/60; pRsp->remain_sms_num = pUsrInfo->bundle_info.sms; pRsp->remain_data_vol = pUsrInfo->bundle_info.data/(1024*1024); } else { pRsp->status = T_EXTERNAL; } // send response msg================ rest_rsp.msg_type = REST_QUERY_USERDATA_RSP; rest_rsp.header.dst_ref = rest_req->header.src_ref; rest_rsp.header.src_ref = rest_req->header.dst_ref; pRsp->error_code = err_code; if (err_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; } else { pRsp->result = RES_SUCCEED; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "reply REST_QUERY_USERDATA_RSP, result[%d]", err_code); } u8 msg_buf[256]; int len = encode_rest_query_user_data_rsp(&rest_rsp, msg_buf); pps_send_rest_msg(msg_buf, len); // return 0; } static int pps_handle_bundle_subs_req(_rest_msg_s *rest_req) { _rest_bundle_subs_req *pReq = &rest_req->msg.bundle_subs_req; _rest_msg_s rest_rsp; _rest_bundle_subs_rsp *pRsp = &rest_rsp.msg.bundle_subs_rsp; int len; PutLogFunID("pps_handle_bundle_subs_req"); // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, pps_handle_bundle_subs_req(), msisdn[%s], pay type[%d], charge[%d]", \ tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn, pReq->payType, pReq->charge); DebugMsg(debugmib.display.asciiOut, "mo[%dMin], mt[%dMin], data[%dMB], sms[%d], valid day[%d]", \ pReq->moVoiceMinute, pReq->mtVoiceMinute, pReq->dataVolume, pReq->smsNum, pReq->validDays); } // log msisdn _account_info user_info; int flag_log_msisdn = 0; memset(pRsp, 0, sizeof(_rest_bundle_subs_rsp)); strcpy((char *)user_info.number, pReq->msisdn); if(logMsgFlag & 0x08) { if(strstr((char *)user_info.number, logMsisdn)) { flag_log_msisdn = 1; } } // get user info int err_code = ERR_REST_SUCCESS; GetAccountPos(&user_info); user_info.status = GetAccountStatus(&user_info); user_info.expired_flag = (u_char)isAccountExpired(&user_info); if ((user_info.status != T_NORMAL) || user_info.expired_flag) { DebugMsg(debugmib.display.asciiOut, "pps_handle_bundle_subs_req(), msisdn[%s], error, status[%d], expired[%d]", \ pReq->msisdn, user_info.status, user_info.expired_flag); err_code = ERR_REST_USER_UNKNOWN;// not found goto out; } int sms_len = 0; char sms_msg[256] = {0}; float charge = 0.0; if (pReq->payType == 1)// pay by balance { charge = (float)pReq->charge; float balance = GetAccountBalance(user_info.head, user_info.tail); if(balance < charge) { DebugMsg(debugmib.display.asciiOut, "pps_handle_bundle_subs_req(), msisdn[%s], balance[%.4f] < request[%.4f]", \ pReq->msisdn, balance, charge); err_code = ERR_REST_CREDIT_LIMIT;// not acceptable sprintf(sms_msg, "%s", getSmsSentenceNative(0, SMS_BUNDLE_PLAN_SUBSCRIBE_NOK)); goto out; } // update balance UpdateAccountBalance(user_info.head, user_info.tail, -charge); } // update bundle info long ret_value[10]; ret_value[0] = 0 - (long)charge; ret_value[1] = pReq->dataVolume; ret_value[2] = pReq->moVoiceMinute; ret_value[3] = pReq->mtVoiceMinute; ret_value[4] = pReq->smsNum; ret_value[5] = pReq->validDays; ret_value[6] = 0; UpdateAccountBundlePlanInfo(&user_info, ret_value); // // sync int instance = user_info.head*UNIT_STORE_ACCOUNT + user_info.tail; SendAccountRealSync(instance, -charge, 0, OMC_OCODE_EDIT); // // send cdr=========================================== SendSelfcareBundleSubCDR(&user_info, (int)charge, pReq->dataVolume*1024, pReq->moVoiceMinute*60); // // set sms string char expire_date[64]; char msg_buf[256] = {0}; GetAccountBundlePlanInfo(&user_info, ret_value); if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "new bundle, data [%ld]MB, mo [%ld]Min, mt [%ld]Min, sms[%ld]", \ ret_value[0], ret_value[1], ret_value[2], ret_value[3]); } AsciiTimeYMD(expire_date, ret_value[4]); sprintf(sms_msg, "%s", getSmsSentenceNative(0, SMS_BUNDLE_PLAN_SUBSCRIBE_OK)); if(ret_value[1]>0 || ret_value[3]>0) { sprintf(msg_buf, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_QUERY), ret_value[0], ret_value[1], // ret_value[2],// disable MT voice ret_value[3], expire_date); } else { sprintf(msg_buf, (char *)getSmsSentenceNative(0, SMS_BUNDLE_PLAN_QUERY_DATA), ret_value[0], expire_date); } strcat(sms_msg, msg_buf); // out: // send sms sms_len = strlen(sms_msg); if (sms_len > 0) { smppSendMOSM(pReq->msisdn, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, (u_char *)sms_msg, sms_len, 0); } // // send response msg================ rest_rsp.msg_type = REST_BUNDLE_SUBS_RSP; rest_rsp.header.dst_ref = rest_req->header.src_ref; rest_rsp.header.src_ref = rest_req->header.dst_ref; pRsp->error_code = err_code; if (err_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; } else { pRsp->result = RES_SUCCEED; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "reply REST_BUNDLE_SUBS_RSP, result[%d]", err_code); } len = encode_rest_bundle_subs_rsp(&rest_rsp, (u8 *)msg_buf); pps_send_rest_msg((u8 *)msg_buf, len); // return 0; } static int pps_handle_bundle_usage_req(_rest_msg_s *rest_req) { _rest_bundle_usage_req *pReq = &rest_req->msg.bundle_usage_req; PutLogFunID("pps_handle_bundle_usage_req"); // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, pps_handle_bundle_usage_req(), msisdn[%s]", \ tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn); } _account_info user_info; int flag_log_msisdn = 0; strcpy((char *)user_info.number, pReq->msisdn); if(logMsgFlag & 0x08) { if(strstr((char *)user_info.number, logMsisdn)) { flag_log_msisdn = 1; } } int err_code = ERR_REST_SUCCESS; _prepaid_info *pUsrInfo = NULL; if ((GetAccountPos(&user_info) == FALSE) || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) { DebugMsg(debugmib.display.asciiOut, "pps_handle_bundle_usage_req(), msisdn[%s], not found", \ pReq->msisdn); err_code = ERR_REST_USER_UNKNOWN;// not found } // set msg _rest_msg_s rest_rsp; _rest_bundle_usage_rsp *pRsp = &rest_rsp.msg.bundle_usage_rsp; memset(pRsp, 0, sizeof(_rest_bundle_usage_rsp)); if (pUsrInfo != NULL) { pRsp->moVoiceInSec = pUsrInfo->bundle_info.mo_voice; pRsp->mtVoiceInSec = pUsrInfo->bundle_info.mt_voice; pRsp->smsNum = pUsrInfo->bundle_info.sms; pRsp->dataVolInKB = pUsrInfo->bundle_info.data/1024; pRsp->expiredTime = pUsrInfo->bundle_info.validity_date; } // // send response msg================ rest_rsp.msg_type = REST_BUNDLE_USAGE_RSP; rest_rsp.header.dst_ref = rest_req->header.src_ref; rest_rsp.header.src_ref = rest_req->header.dst_ref; pRsp->error_code = err_code; if (err_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; } else { pRsp->result = RES_SUCCEED; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "reply REST_BUNDLE_USAGE_RSP, result[%d], data[%d]KB, mo[%d]sec, mt[%d]sec, sms[%d]", err_code, pRsp->dataVolInKB, pRsp->moVoiceInSec, pRsp->mtVoiceInSec, pRsp->smsNum); } u8 msg_buf[256]; int len = encode_rest_bundle_usage_rsp(&rest_rsp, msg_buf); pps_send_rest_msg(msg_buf, len); // return 0; } static int pps_handle_recharge_req(_rest_msg_s *rest_req) { _rest_recharge_req *pReq = &rest_req->msg.recharge_req; int len; int op_type = CT_ASSISTED_UP; u8 msg_buf[256]; int flag_log_msisdn = 0; _account_info user_info; int err_code = ERR_REST_SUCCESS; char sms_msg[256] = {0}; int balance; float recharge; _prepaid_info *pUserInfo = NULL; _rest_msg_s rest_rsp; _rest_recharge_rsp *pRsp = &rest_rsp.msg.recharge_rsp; PutLogFunID("pps_handle_recharge_req"); // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, pps_handle_recharge_req(), op_type=%d, msisdn[%s], amount[%d]", \ tvnow.tv_sec, tvnow.tv_usec/1000, pReq->op_type, pReq->msisdn, pReq->amount); } strcpy((char *)user_info.number, pReq->msisdn); if(logMsgFlag & 0x08) { if(strstr((char *)user_info.number, logMsisdn)) { flag_log_msisdn = 1; } } GetAccountPos(&user_info); user_info.status = GetAccountStatus(&user_info); user_info.expired_flag = (u_char)isAccountExpired(&user_info); user_info.cos_id = (u_char)GetCosIDByAccount(&user_info); if ((user_info.status != T_NORMAL && user_info.status != T_FRESH && user_info.status != T_SUSPEND && user_info.status != T_DISABLE)) // if ((user_info.status != T_NORMAL && user_info.status != T_FRESH && user_info.status != T_SUSPEND) || user_info.expired_flag) { DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_req(), msisdn[%s], error, status[%d], expired[%d]", \ pReq->msisdn, user_info.status, user_info.expired_flag); err_code = ERR_REST_USER_UNKNOWN;// not found goto out; } memset(pRsp, 0, sizeof(_rest_recharge_rsp)); balance = (int)GetAccountBalance(user_info.head, user_info.tail); if(pReq->op_type == 0) { if (balance < pReq->amount ) { DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_req(), msisdn[%s], balance[%d] exceed maximum[%d]", \ pReq->msisdn, (balance + pReq->amount), ppsParam.serviceControl.maxBalance); err_code = ERR_REST_CREDIT_LIMIT; sprintf(sms_msg, "%s", "Recharge failed, you have exceeded your maximum balance."); smppSendMOSM(pReq->msisdn, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, (u_char *)sms_msg, strlen(sms_msg), 0); goto out; } op_type = CT_ASSISTED_DOWN; recharge = (-1)*(float)pReq->amount; } else if(pReq->op_type == 1) { if ((balance + pReq->amount) >= ppsParam.serviceControl.maxBalance) { DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_req(), msisdn[%s], balance[%d] exceed maximum[%d]", \ pReq->msisdn, (balance + pReq->amount), ppsParam.serviceControl.maxBalance); err_code = ERR_REST_INVALID_PARAMETER_VALUE; sprintf(sms_msg, "%s", "Recharge failed, you have exceeded your maximum balance."); smppSendMOSM(pReq->msisdn, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, (u_char *)sms_msg, strlen(sms_msg), 0); goto out; } op_type = CT_ASSISTED_UP; recharge = (float)pReq->amount; } else { err_code = ERR_REST_INVALID_PARAMETER_VALUE; sprintf(sms_msg, "%s", "Recharge failed, wrong op_type."); goto out; } // update balance //UpdateAccountBalance(user_info.head, user_info.tail, pReq->amount); UpdateAccountBalance(user_info.head, user_info.tail, recharge); pUserInfo = getPrepaidInfo(&user_info); // send cdr===================================================== SendSelfcareRechargeCDR(&user_info, "", op_type, (int)pReq->amount); // update status COSTable *cosTableItem = &ppsParam.ppsTables.cosTable[user_info.cos_id]; if (T_FRESH == user_info.status) { // update first used date //int index; //int mo_valid_time = 30, mt_valid_time = 30; /* _prepaid_data *shmp = &ramshm_ptr->prepaid_data; if((index=GetCardSystemParamByNearestValue(user_info.cos_id, (u_short)pReq->amount))>=0){ mo_valid_time = cosTableItem->rechargeCardValidity[index].moValidity; mt_valid_time = cosTableItem->rechargeCardValidity[index].mtValidity; } */ /* mo_valid_time = mt_valid_time = pReq->valid_days; if(mo_valid_time<=0) mo_valid_time = mt_valid_time = 1; shmp->prepaid_info[user_info.head][user_info.tail].mo_expiration_date = mo_valid_time*24*60*60 + tvnow.tv_sec; shmp->prepaid_info[user_info.head][user_info.tail].mt_expiration_date = mt_valid_time*24*60*60 + tvnow.tv_sec; */ UpdateAccountFirstUsedDate(user_info.head, user_info.tail); UpdateExpirationForRechargeCard(&user_info, pReq->valid_days, (u_short)pReq->amount); UpdateAccountStatus(user_info.head, user_info.tail, T_NORMAL); } else { if(op_type == CT_ASSISTED_UP) { int old_status=0x00; old_status = GetAccountStatus(&user_info); UpdateExpirationForRechargeCard(&user_info, pReq->valid_days, (u_short)pReq->amount); UpdateAccountStatus(user_info.head, user_info.tail, T_NORMAL); if(old_status != T_NORMAL && old_status != T_FRESH) pps_send_update_subs_status_to_crm(pUserInfo, 1); //update status to CRM , may then invoke procedures towards HLR/HSS } } // // Sync u32 instance = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; SendAccountRealSync(instance, recharge, 0.0, OMC_OCODE_EDIT); // send notification sms if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenRecharge) { SendAccountInfoBySMPP(&user_info, ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); } // set respons msg pRsp->status = GetAccountStatus(&user_info); pRsp->balance = GetBalance(&user_info); pRsp->expiredTime = (u64)GetExpiration(&user_info); if(pUserInfo->cug_id>0 && pUserInfo->crm_info.vas_cug_state>0) { pps_send_rent_charge_to_crm(user_info.head, user_info.tail); } out: // send response msg================ rest_rsp.msg_type = REST_RECHARGE_RSP; rest_rsp.header.dst_ref = rest_req->header.src_ref; rest_rsp.header.src_ref = rest_req->header.dst_ref; pRsp->error_code = err_code; if (err_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; } else { pRsp->result = RES_SUCCEED; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "reply REST_RECHARGE_RSP, result[%d], balance[%d]", err_code, pRsp->balance); } len = encode_rest_recharge_rsp(&rest_rsp, msg_buf); pps_send_rest_msg(msg_buf, len); // return 0; } extern int isChildTransferAllowed(_prepaid_info *prepaidInfo); extern int checkTransferedPartialFee(_account_info *callerInfo, float feeTransfered); static int pps_handle_transfer_req(_rest_msg_s *rest_req) { _rest_transfer_req *pReq = &rest_req->msg.transfer_req; int err_code = ERR_REST_SUCCESS, len; u8 msg_buf[256]; u_char tmp[MAX_SMS_LEN*4] = {0}; PutLogFunID("pps_handle_transfer_req"); // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, pps_handle_transfer_req(), transfer out[%s], in[%s], amount[%d]", \ tvnow.tv_sec, tvnow.tv_usec/1000, pReq->transferOutMsisdn, pReq->transferInMsisdn, pReq->amount); } _account_info user_info; strcpy((char *)user_info.number, pReq->transferOutMsisdn); // check log msisdn int flag_log_msisdn = 0; if(logMsgFlag & 0x08) { if(strstr((char *)user_info.number, logMsisdn)) { flag_log_msisdn = 1; } } // check param _rest_msg_s rest_rsp; _rest_transfer_rsp *pRsp = &rest_rsp.msg.transfer_rsp; memset(pRsp, 0, sizeof(_rest_transfer_rsp)); if ((pReq->amount == 0) || (strlen(pReq->transferOutMsisdn) == 0) || (strlen(pReq->transferInMsisdn) == 0)) { if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "pps_handle_transfer_req(), err param, transfer out msisdn[%s]", pReq->transferOutMsisdn); } goto out; } // check src number _prepaid_info *prepaidInfo = NULL; GetAccountPos(&user_info); if ((GetAccountStatus(&user_info) != T_NORMAL)\ || ((prepaidInfo = getPrepaidInfo(&user_info)) == NULL)\ || ((prepaidInfo->poolAccount.role == MASTER_SLAVE_CHILD)\ && (isChildTransferAllowed(prepaidInfo) == FALSE))) { strcpy((char *)tmp, (char *)getSmsSentenceNative(0, SMS_SERVICE_NOT_APPLIED)); smppSendMsg((u_char *)pReq->transferOutMsisdn, tmp, FeeTransferPosition); if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "src number[%s], SMS_SERVICE_NOT_APPLIED", pReq->transferOutMsisdn); } err_code = ERR_REST_USER_UNKNOWN;// not found goto out; } // check transfer fee float amount = (float)pReq->amount; int result = checkTransferedPartialFee(&user_info, amount); switch(result) { case CHECK_TRANSFERED_FEE_INSUFFIENT: strcpy((char *)tmp, (char *)getSmsSentenceNative(0, SMS_INSUFFICIENT_FEE)); smppSendMsg((u_char *)pReq->transferOutMsisdn, tmp, FeeTransferPosition); if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "src number[%s], SMS_INSUFFICIENT_FEE", pReq->transferOutMsisdn); } err_code = ERR_REST_CREDIT_LIMIT; goto out; break; case CHECK_TRANSFERED_FEE_EXPIERED: strcpy((char *)tmp, (char *)getSmsSentenceNative(0, SMS_EXPIRED_ACCOUNT)); smppSendMsg((u_char *)pReq->transferOutMsisdn, tmp, FeeTransferPosition); if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "src number[%s], SMS_EXPIRED_ACCOUNT", pReq->transferOutMsisdn); } err_code = ERR_REST_INVALID_USER_STATUS; goto out; break; default: break; } // // check dst number _account_info dst_user; strcpy((char *)dst_user.number, pReq->transferInMsisdn); int bDstAllowFlag = 0; if (GetAccountPos(&dst_user) == TRUE) { if (get_transfer_status_normal_flag()) { int status = GetAccountStatus(&dst_user); if ((status == T_NORMAL) || (status == T_FRESH) || (status == T_SUSPEND)) { bDstAllowFlag = 1; } } else { bDstAllowFlag = 1; } } if (!bDstAllowFlag) { strcpy((char *)tmp, (char *)getSmsSentenceNative(0, SMS_INVALID_NUMBER)); smppSendMsg((u_char *)pReq->transferOutMsisdn, tmp, FeeTransferPosition); if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "dst number[%s], SMS_INVALID_NUMBER", pReq->transferInMsisdn); } err_code = ERR_REST_DEST_USER_NOT_ALLOWED; goto out; } // // fee transfer poolTransferAccount(&user_info, &dst_user, amount); if(OCS_with_external_CRM() == 0) { notifyUserTransferResult_1(&user_info, &dst_user, (int)amount, NOTIFY_CALLER); notifyUserTransferResult_1(&user_info, &dst_user, (int)amount, NOTIFY_CALLED); } // send cdr float charge = (float)pReq->amount; SendSelfcareTransferCDR(&user_info, &dst_user, -charge); SendSelfcareTransferCDR(&dst_user, &user_info, charge); // // set response message pRsp->balance = (u32)GetAccountBalance(user_info.head, user_info.tail); out: // send response msg================ rest_rsp.msg_type = REST_TRANSFER_RSP; rest_rsp.header.dst_ref = rest_req->header.src_ref; rest_rsp.header.src_ref = rest_req->header.dst_ref; pRsp->error_code = err_code; if (err_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; } else { pRsp->result = RES_SUCCEED; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "reply REST_TRANSFER_RSP, result[%d], balance[%d]", err_code, pRsp->balance); } len = encode_rest_transfer_rsp(&rest_rsp, msg_buf); pps_send_rest_msg(msg_buf, len); // return 0; } extern _climax_quence climaxQuence; extern int GetClimaxQuenceStorePos(u_char *card_pwd,int start,int end); extern int pps_real_update_card_file(int head, int tail); static int pps_handle_recharge_card_req(_rest_msg_s *rest_req) { _rest_recharge_card_req *pReq = &rest_req->msg.recharge_card_req; int err_code = ERR_REST_SUCCESS, len; u8 msg_buf[256]; char sms_msg[256] = {0}; PutLogFunID("pps_handle_recharge_card_req"); // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, pps_handle_recharge_card_req(), msisdn[%s]", \ tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn); } _account_info user_info; int flag_log_msisdn = 0; strcpy((char *)user_info.number, pReq->msisdn); if(logMsgFlag & 0x08) { if(strstr((char *)user_info.number, logMsisdn)) { flag_log_msisdn = 1; } } _rest_msg_s rest_rsp; _rest_recharge_card_rsp *pRsp = &rest_rsp.msg.recharge_card_rsp; memset(pRsp, 0, sizeof(_rest_recharge_card_rsp)); GetAccountPos(&user_info); user_info.status = GetAccountStatus(&user_info); user_info.expired_flag = isAccountExpired(&user_info); user_info.cos_id = GetCosIDByAccount(&user_info); if ((user_info.status != T_NORMAL && user_info.status != T_FRESH && user_info.status != T_SUSPEND) || user_info.expired_flag) { DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], error status[%d] or expired[%d]", \ pReq->msisdn, user_info.status, user_info.expired_flag); err_code = ERR_REST_USER_UNKNOWN;// not found goto out; } len = strlen(pReq->cardPwd);/* to judge length of pwd,6,8 */ if(len <10 || len >16) { SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_FAIL, 0); DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], error pwd len[%d]", \ pReq->msisdn, len); err_code = ERR_REST_INVALID_RECHARGE_PWD; goto fail; } if(OCS_with_external_CRM()) { int proc_id = 0; _state_data *shmp; proc_id = AssignProcID(0); if(proc_id<0) return 0; shmp = (_state_data *)&smshm_ptr->state_data; shmp += proc_id; shmp->process_info.portid = proc_id; memcpy(&shmp->caller_info, &user_info, sizeof(_account_info)); strcpy((char *)shmp->called_info.number, pReq->cardPwd); shmp->process_info.state = S_SMMP_RECHAGE_ACCOUNT; shmp->process_info.chargeFrom = 3; shmp->process_info.sub_state = 2; shmp->process_info.rest_if.src_ref = rest_req->header.src_ref; shmp->process_info.rest_if.dst_ref = proc_id; return 1; } char card_pwd[64]=""; int cardsqu = 0, cardtail = 0; _recharge_card_info *cardshmp = NULL; EncryptCardHRN(pReq->cardPwd, (u_char *)card_pwd); if((cardsqu = GetClimaxQuenceStorePos((u_char *)card_pwd, 0, climaxQuence.counter)) < 0) { SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_FAIL, 0); DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], card not found", \ pReq->msisdn); err_code = ERR_REST_INVALID_RECHARGE_PWD; goto fail; } cardtail = cardsqu % MAX_CARD_NUM_PSEG; cardsqu = cardsqu / MAX_CARD_NUM_PSEG; cardshmp=&ramshm_ptr->card_data.prepaid_card[cardsqu][cardtail]; if(memcmp(card_pwd, cardshmp->card_pwd, MAX_CARD_HRN_BLEN)) { /* error password */ DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], error pwd", \ pReq->msisdn); err_code = ERR_REST_INVALID_RECHARGE_PWD; goto fail; } if(cardshmp->card_status != CARD_FRESH) { SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_FAIL, 0); DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], card already used", \ pReq->msisdn); err_code = ERR_REST_INVALID_RECHARGE_PWD; goto fail; } if(cardshmp->expiry_date < time(NULL)) { SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_FAIL, 0); DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], card expired", \ pReq->msisdn); err_code = ERR_REST_INVALID_RECHARGE_PWD; goto fail; } int balance = (int)GetAccountBalance(user_info.head, user_info.tail); if ((balance + cardshmp->face_value) >= ppsParam.serviceControl.maxBalance) { SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_FAIL, 0); DebugMsg(debugmib.display.asciiOut, "pps_handle_recharge_card_req(), msisdn[%s], balance[%d] exceed maximum[%d]", \ pReq->msisdn, (balance + cardshmp->face_value), ppsParam.serviceControl.maxBalance); err_code = ERR_REST_UNABLE_TO_COMPLY; sprintf(sms_msg, "%s", "Recharge failed, you have exceeded your maximum balance."); smppSendMOSM(pReq->msisdn, (char *)ppsParam.ppsTables.serviceNumber[InquiryNumberPosition].number, (u_char *)sms_msg, strlen(sms_msg), 0); goto fail; } // update balance float amount = (float)cardshmp->face_value; UpdateAccountBalance(user_info.head, user_info.tail, amount); // update card cardshmp->card_status = CARD_USED; cardshmp->updated_date = tvnow.tv_sec; strcpy(cardshmp->msisdn_used, pReq->msisdn); SendPrepaidCardRealSync(cardsqu*MAX_CARD_NUM_PSEG+cardtail, 5);//delete pps_real_update_card_file(cardsqu, cardtail); // // send cdr===================================================== SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_SUCCESS, (int)cardshmp->face_value); // update status COSTable *cosTableItem = &ppsParam.ppsTables.cosTable[user_info.cos_id]; if (T_FRESH == user_info.status) { // update first used date int index; int mo_valid_time = cardshmp->valid_time, mt_valid_time = cardshmp->valid_time; _prepaid_data *shmp = &ramshm_ptr->prepaid_data; if((index=GetCardSystemParam(user_info.cos_id, (u_short)cardshmp->face_value))>=0){ mo_valid_time = cosTableItem->rechargeCardValidity[index].moValidity; mt_valid_time = cosTableItem->rechargeCardValidity[index].mtValidity; } shmp->prepaid_info[user_info.head][user_info.tail].mo_expiration_date = mo_valid_time*24*60*60 + tvnow.tv_sec; shmp->prepaid_info[user_info.head][user_info.tail].mt_expiration_date = mt_valid_time*24*60*60 + tvnow.tv_sec; // UpdateAccountFirstUsedDate(user_info.head, user_info.tail); UpdateAccountStatus(user_info.head, user_info.tail, T_NORMAL); } else { UpdateExpirationForRechargeCard(&user_info, cardshmp->valid_time, (u_short)cardshmp->face_value); UpdateAccountStatus(user_info.head, user_info.tail, T_NORMAL); } // // promotion int promo_balance = 0; if(IsPromotionTime(cosTableItem, tvnow)) { int promo_balance = GetPromotionAmount(cosTableItem, (int)cardshmp->face_value); if(promo_balance !=0) { UpdateAccountPromotionBalance(user_info.head, user_info.tail, (float)promo_balance); UpdateAccountPromotionExpiryDay(user_info.head, user_info.tail, GetPromotionDay(cosTableItem, cardshmp->face_value)); // send cdr========================================================================== //shmp->cdr_info.answertime = tvnow.tv_sec + 1; SendSelfcareRechargeCDR(&user_info, pReq->cardPwd, CT_RECHARGE_SUCCESS, promo_balance); } } // // Sync u32 instance = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; ResetAccountRechargeFail(user_info.head, user_info.tail); resetCMBTimes(&user_info); SendAccountRealSync(instance, amount, promo_balance, OMC_OCODE_EDIT); // send notification sms if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenRecharge) { SendAccountInfoBySMPP(&user_info, ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); } // set respons msg pRsp->balance = GetBalance(&user_info); pRsp->rechargeAmount = (u32)cardshmp->face_value; pRsp->expiredTime = (u64)GetExpiration(&user_info); goto out; fail: // send cdr========================================================== //SendRechargeCDR(proc_id, CT_RECHARGE_FAIL, 0); UpdateAccountRechargeFail(user_info.head, user_info.tail); int maxThreshold = GetParamRechargeAttemptLimit(); if ((maxThreshold>0) && (maxThreshold < GetAccountRechargeFail(user_info.head, user_info.tail))) { UpdateAccountStatus(user_info.head, user_info.tail, T_BLACKLIST); ResetAccountRechargeFail(user_info.head, user_info.tail); } instance = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; SendAccountRealSync(instance, 0.0, 0.0, OMC_OCODE_EDIT); out: // send response msg================ rest_rsp.msg_type = REST_RECHARGE_CARD_RSP; rest_rsp.header.dst_ref = rest_req->header.src_ref; rest_rsp.header.src_ref = rest_req->header.dst_ref; pRsp->error_code = err_code; if (err_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; } else { pRsp->result = RES_SUCCEED; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "reply REST_RECHARGE_CARD_RSP, result[%d], recharge amount[%d], balance[%d]", \ err_code, pRsp->rechargeAmount, pRsp->balance); } len = encode_rest_recharge_card_rsp(&rest_rsp, msg_buf); pps_send_rest_msg(msg_buf, len); // return 0; } static int pps_handle_check_balance_req(_rest_msg_s *rest_req) { _rest_check_balance_req *pReq = &rest_req->msg.check_balance_req; PutLogFunID("pps_handle_check_balance_req"); // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, pps_handle_check_balance_req(), msisdn[%s], amount[%d]", \ tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn, pReq->amount); } _account_info user_info; int flag_log_msisdn = 0; strcpy((char *)user_info.number, pReq->msisdn); if(logMsgFlag & 0x08) { if(strstr((char *)user_info.number, logMsisdn)) { flag_log_msisdn = 1; } } _prepaid_info *pUsrInfo = NULL; int err_code = ERR_REST_SUCCESS; if ((GetAccountPos(&user_info) == FALSE) || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) { DebugMsg(debugmib.display.asciiOut, "pps_handle_check_balance_req(), msisdn[%s], not found", \ pReq->msisdn); err_code = ERR_REST_USER_UNKNOWN;// not found } // set msg _rest_msg_s rest_rsp; _rest_check_balance_rsp *pRsp = &rest_rsp.msg.check_balance_rsp; memset(pRsp, 0, sizeof(_rest_check_balance_rsp)); if (pUsrInfo != NULL) { if ((pUsrInfo->status != T_NORMAL) || (pUsrInfo->balance < pReq->amount)) { pRsp->available = 1;// not enough balance } else { pRsp->available = 0;// enough balance } } // // send response msg================ rest_rsp.msg_type = REST_CHECK_BALANCE_RSP; rest_rsp.header.dst_ref = rest_req->header.src_ref; rest_rsp.header.src_ref = rest_req->header.dst_ref; pRsp->error_code = err_code; if (err_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; } else { pRsp->result = RES_SUCCEED; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "reply REST_CHECK_BALANCE_RSP, result[%d]", err_code); } u8 msg_buf[256]; int len = encode_rest_check_balance_rsp(&rest_rsp, msg_buf); pps_send_rest_msg(msg_buf, len); // return 0; } static int pps_handle_query_balance_req(_rest_msg_s *rest_req) { _rest_query_balance_req *pReq = &rest_req->msg.query_balance_req; PutLogFunID("pps_handle_query_balance_req"); // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, pps_handle_query_balance_req(), msisdn[%s]", \ tvnow.tv_sec, tvnow.tv_usec/1000, pReq->msisdn); } int flag_log_msisdn = 0; _account_info user_info; strcpy((char *)user_info.number, pReq->msisdn); if(logMsgFlag & 0x08) { if(strstr((char *)user_info.number, logMsisdn)) { flag_log_msisdn = 1; } } _prepaid_info *pUsrInfo = NULL; int err_code = ERR_REST_SUCCESS; if ((GetAccountPos(&user_info) == FALSE) || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) { DebugMsg(debugmib.display.asciiOut, "pps_handle_query_balance_req(), msisdn[%s], not found", \ pReq->msisdn); err_code = ERR_REST_USER_UNKNOWN;// not found } // set msg _rest_msg_s rest_rsp; _rest_query_balance_rsp *pRsp = &rest_rsp.msg.query_balance_rsp; memset(pRsp, 0, sizeof(_rest_query_balance_rsp)); if (pUsrInfo != NULL) { if(pUsrInfo->status == T_NORMAL ) { UpdateAccountStatusFromNormalToSuspendedforExpiration(pUsrInfo, user_info.head, user_info.tail); } //if (pUsrInfo->status == T_NORMAL) { pRsp->status = pUsrInfo->status; pRsp->balance = (u32)pUsrInfo->balance; pRsp->mo_expiry = (u32)pUsrInfo->mo_expiration_date; } } // // send response msg================ rest_rsp.msg_type = REST_QUERY_BALANCE_RSP; rest_rsp.header.dst_ref = rest_req->header.src_ref; rest_rsp.header.src_ref = rest_req->header.dst_ref; pRsp->error_code = err_code; if (err_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; } else { pRsp->result = RES_SUCCEED; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) || flag_log_msisdn) { DebugMsg(debugmib.display.asciiOut, "reply REST_QUERY_BALANCE_RSP, result[%d]", err_code); } u8 msg_buf[256]; int len = encode_rest_query_balance_rsp(&rest_rsp, msg_buf); pps_send_rest_msg(msg_buf, len); // return 0; } int pps_handle_crm_sms_deliver_req(_rest_msg_s *rest_req) { _rest_sms_deliver_req *pReq = &rest_req->msg.sms_deliver; int err_code = ERR_REST_SUCCESS; u8 msg_buf[256]; int len; _rest_msg_s rest_rsp; _rest_sms_deliver_res *pRsp = &rest_rsp.msg.sms_deliver_res; PutLogFunID("pps_handle_crm_sms_deliver_req"); // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, %s, msisdn[%s]", \ tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, pReq->msisdn); } // set msg memset(pRsp, 0, sizeof(_rest_sms_deliver_res)); // send response msg================ rest_rsp.msg_type = REST_CRM_SMS_DELIVER_RES; rest_rsp.header.dst_ref = rest_req->header.src_ref; rest_rsp.header.src_ref = rest_req->header.dst_ref; pRsp->error_code = err_code; if (err_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; } else { pRsp->result = RES_SUCCEED; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) ) { DebugMsg(debugmib.display.asciiOut, "reply CRM_SMS_DELIVER_RSP, result[%d]", err_code); } len = encode_rest_sms_deliver_res(&rest_rsp, msg_buf); pps_send_rest_msg(msg_buf, len); len = strlen(pReq->sms_content); smppSendMOSM(pReq->msisdn, pps_get_service_number(HotLineNumberPosition), (u_char *)pReq->sms_content, len, 0); return 1; } int pps_handle_crm_create_account_req(_rest_msg_s *rest_req) { _rest_create_acct_req *pReq = &rest_req->msg.create_acct; int err_code = ERR_REST_SUCCESS; u8 msg_buf[256]; int len, user_index=0; _account_info user_info; //int flag_log_msisdn = 0; int ocode=OMC_OCODE_EDIT; _prepaid_info *pUsrInfo = NULL; int dif_balance = 0; _prepaid_info *shmp=NULL,tmpSubsData; _rest_msg_s rest_rsp; _rest_create_acct_res *pRsp = &rest_rsp.msg.create_acct_res; PutLogFunID("pps_handle_crm_create_account_req"); // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, %s, msisdn[%s]", \ tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, pReq->msisdn); } strcpy((char *)user_info.number, pReq->msisdn); if(logMsgFlag & 0x08) { if(strstr((char *)user_info.number, logMsisdn)) { //flag_log_msisdn = 1; } } if ((GetAccountPos(&user_info) == FALSE) || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) { //create it, check license if(debugmib.measurement.usernumber>=ppsParam.serviceControl.licenseduser) { DebugMsg(debugmib.display.asciiOut, "pps_handle_crm_create_account_req(), exist users %d >= licensed user(%ld)!" , debugmib.measurement.usernumber, ppsParam.serviceControl.licenseduser); err_code = ERR_REST_NO_LICENSE; goto ret_err; } shmp = &tmpSubsData; memset(shmp, 0x00, sizeof(_prepaid_info)); len = strlen(pReq->msisdn); shmp->msisdn[MAX_MSISDN_BLEN-1] = len; AsciiToBcd(shmp->msisdn, pReq->msisdn, (len+1)/2*2); strcpy(shmp->pin, "123456"); shmp->balance = pReq->balance; shmp->mo_expiration_date = shmp->mt_expiration_date = pReq->expiry_date; shmp->crm_info.customer_id = pReq->customer_id; shmp->crm_info.account_id = pReq->account_id; shmp->crm_info.product_id = pReq->product_id; shmp->crm_info.base_plan_id = pReq->plan_id; shmp->crm_info.user_class = pReq->user_class; shmp->crm_info.birthday = pReq->birthday; shmp->crm_info.rent_charge = pReq->rent_charge; shmp->cug_id = pReq->cug_id; shmp->status = T_NORMAL; dif_balance = pReq->balance; user_index = AddPPSSubsData(shmp); ocode = OMC_OCODE_ADD; DebugMsg(debugmib.display.asciiOut, "pps_handle_crm_create_account_req(), msisdn[%s], not found", \ pReq->msisdn); } else { DebugMsg(debugmib.display.asciiOut, "pps_handle_crm_create_account_req(), msisdn[%s], already exsits", \ pReq->msisdn); //update dif_balance = pReq->balance - pUsrInfo->balance; pps_update_user_info_for_crm_create_account(pUsrInfo, pReq->customer_id, pReq->account_id, pReq->product_id, pReq->plan_id, pReq->balance, pReq->expiry_date, pReq->rent_charge, pReq->birthday, pReq->cug_id); user_index = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; ocode = OMC_OCODE_EDIT; } //sync... if(1) { int head = user_index / UNIT_STORE_ACCOUNT; int tail = user_index % UNIT_STORE_ACCOUNT; if(dif_balance != 0) { SendOperatorRechargeCDR(head,tail,dif_balance); AccountLatchFlagCheck(head,tail); pps_real_update_user_file(head, tail); } SendAccountRealSync(user_index,dif_balance,0,ocode); } ret_err: // set msg memset(pRsp, 0, sizeof(_rest_create_acct_res)); // send response msg================ rest_rsp.msg_type = REST_CRM_CREATE_ACCT_RES; rest_rsp.header.dst_ref = rest_req->header.src_ref; rest_rsp.header.src_ref = rest_req->header.dst_ref; pRsp->error_code = err_code; if (err_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; } else { pRsp->result = RES_SUCCEED; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) ) { DebugMsg(debugmib.display.asciiOut, "reply CRM_CREATE_ACCOUNT_RSP, result[%d]", err_code); } len = encode_rest_create_account_res(&rest_rsp, msg_buf); pps_send_rest_msg(msg_buf, len); if(0)//CRM should send a Welcome message to new created user { char sms_content[256]; strcpy(sms_content, (char *)getSmsSentenceNative(0,SMS_ACTIVATION_NOTIFY)); len = strlen(sms_content); smppSendMOSM(pReq->msisdn, pps_get_service_number(HotLineNumberPosition), (u_char *)sms_content, len, 0); } return 1; } int pps_handle_crm_query_tariff_res(_rest_msg_s *rest_res) { int portid; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _rest_query_tariff_res *pRes = &rest_res->msg.query_tariff_res; PutLogFunID("pps_handle_crm_query_tariff_res"); portid = rest_res->header.dst_ref; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += portid; if(shmp->process_info.rest_if.query_tariff_status != 1) { if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, %s, port[%d] is not waiting for query tariff result", \ tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, portid); } return -1; } if(pRes->result != 0) { shmp->process_info.rest_if.query_tariff_status = 3; //not found // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, %s, no data tariff errcode[%d]", \ tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, pRes->error_code); } return 0; } { shmp->process_info.rest_if.query_tariff_status = 2; //succeed /* shmp->process_info.tariff.unit_time = pRes->unit_time; shmp->process_info.tariff.tierRating.tierNumber = 0; shmp->process_info.tariff.tierRating.rating[0].base_fee = pRes->unit_charge; */ shmp->process_info.rest_if.unit = pRes->unit_time; shmp->process_info.rest_if.unit_charge = pRes->unit_charge*1.0/100.0; //in CRM, the unit is *100 for better precision shmp->process_info.rest_if.tariff_discount = pRes->discount; shmp->process_info.rest_if.plan_id = pRes->plan_id; shmp->process_info.rest_if.bundle_plan_id = pRes->bundle_plan_id; shmp->process_info.rest_if.total_plan_value = pRes->total_plan_value; shmp->process_info.rest_if.used_plan_value = pRes->used_plan_value; if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, %s, port[%d] tariff: %d*%6.3f * %d, %lld-%lld", \ tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, portid, pRes->unit_time, shmp->process_info.rest_if.unit_charge, pRes->discount, pRes->total_plan_value, pRes->used_plan_value); } } return 1; } int pps_handle_crm_update_subs(_rest_msg_s *rest_req) { _rest_update_subs_req *pReq = &rest_req->msg.update_subs; int err_code = ERR_REST_SUCCESS; u8 msg_buf[256]; int len, user_index=0; _account_info user_info; //int flag_log_msisdn = 0; int ocode=OMC_OCODE_EDIT; _prepaid_info *pUsrInfo = NULL; int dif_balance = 0; //_prepaid_info *shmp=NULL;//,tmpSubsData; _rest_msg_s rest_rsp; _rest_update_subs_res *pRsp = &rest_rsp.msg.update_subs_res; PutLogFunID("pps_handle_crm_update_subs"); // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, %s, msisdn[%s]", \ tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, pReq->msisdn); } strcpy((char *)user_info.number, pReq->msisdn); if(logMsgFlag & 0x08) { if(strstr((char *)user_info.number, logMsisdn)) { //flag_log_msisdn = 1; } } if ((GetAccountPos(&user_info) == FALSE) || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) { DebugMsg(debugmib.display.asciiOut, "pps_handle_crm_update_subs(), msisdn[%s], not found", \ pReq->msisdn); err_code = ERR_REST_USER_UNKNOWN; goto ret_err; } else { DebugMsg(debugmib.display.asciiOut, "pps_handle_crm_update_subs(), msisdn[%s]", \ pReq->msisdn); if((pReq->optional_flag & 0x01) == 0x01) pUsrInfo->status = pReq->status; //check if valid status if((pReq->optional_flag & 0x02) == 0x02) { pUsrInfo->balance = pReq->balance; dif_balance = pReq->balance - pUsrInfo->balance; } if((pReq->optional_flag & 0x04) == 0x04) pUsrInfo->mo_expiration_date = pUsrInfo->mt_expiration_date = pReq->balance_expiry_date; if((pReq->optional_flag & 0x08) == 0x08) pUsrInfo->crm_info.new_plan_id = pReq->basic_plan_id; if((pReq->optional_flag & 0x10) == 0x10) pUsrInfo->crm_info.new_rent_charge = pReq->basic_plan_rent; if((pReq->optional_flag & 0x20) == 0x20) pUsrInfo->crm_info.vas_cug_state = pReq->vas_cug_status; user_index = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; ocode = OMC_OCODE_EDIT; } //sync... if(1) { int head = user_index / UNIT_STORE_ACCOUNT; int tail = user_index % UNIT_STORE_ACCOUNT; if(dif_balance != 0) { SendOperatorRechargeCDR(head,tail,dif_balance); AccountLatchFlagCheck(head,tail); pps_real_update_user_file(head, tail); } SendAccountRealSync(user_index,dif_balance,0,ocode); } ret_err: // set msg memset(pRsp, 0, sizeof(_rest_update_subs_res)); // send response msg================ rest_rsp.msg_type = REST_CRM_UPDATE_SUBS_RES; rest_rsp.header.dst_ref = rest_req->header.src_ref; rest_rsp.header.src_ref = rest_req->header.dst_ref; pRsp->error_code = err_code; if (err_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; } else { pRsp->result = RES_SUCCEED; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) ) { DebugMsg(debugmib.display.asciiOut, "reply CRM_UPDATE_SUBS_RSP, result[%d]", err_code); } len = encode_rest_update_subs_res(&rest_rsp, msg_buf); pps_send_rest_msg(msg_buf, len); return 1; } int pps_handle_crm_delete_subs(_rest_msg_s *rest_req) { _rest_delete_subs_req *pReq = &rest_req->msg.delete_subs; int err_code = ERR_REST_SUCCESS; u8 msg_buf[256]; int len, user_index=0; _account_info user_info; //int flag_log_msisdn = 0; int ocode=OMC_OCODE_DEL; _prepaid_info *pUsrInfo = NULL; int dif_balance = 0; _rest_msg_s rest_rsp; _rest_delete_subs_res *pRsp = &rest_rsp.msg.delete_subs_res; PutLogFunID("pps_handle_crm_delete_subs"); // log message if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, %s, msisdn[%s]", \ tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, pReq->msisdn); } strcpy((char *)user_info.number, pReq->msisdn); if(logMsgFlag & 0x08) { if(strstr((char *)user_info.number, logMsisdn)) { //flag_log_msisdn = 1; } } if ((GetAccountPos(&user_info) == FALSE) || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) { DebugMsg(debugmib.display.asciiOut, "%s, msisdn[%s], not found", __FUNCTION__, pReq->msisdn); err_code = ERR_REST_USER_UNKNOWN; goto ret_err; } else { DebugMsg(debugmib.display.asciiOut, "%s, msisdn[%s], found", __FUNCTION__, pReq->msisdn); dif_balance = pUsrInfo->balance; user_index = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; ocode = OMC_OCODE_DEL; } //sync... if(1) { int head = user_index / UNIT_STORE_ACCOUNT; int tail = user_index % UNIT_STORE_ACCOUNT; if(dif_balance != 0) { SendOperatorRechargeCDR(head, tail, 0-dif_balance); // pps_real_update_user_file(head, tail); } SendAccountRealSync(user_index, 0-dif_balance, 0, ocode); DeletePPSSubsData(pUsrInfo); } ret_err: // set msg memset(pRsp, 0, sizeof(_rest_delete_subs_res)); // send response msg================ rest_rsp.msg_type = REST_CRM_UPDATE_SUBS_RES; rest_rsp.header.dst_ref = rest_req->header.src_ref; rest_rsp.header.src_ref = rest_req->header.dst_ref; pRsp->error_code = err_code; if (err_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; } else { pRsp->result = RES_SUCCEED; } if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) ) { DebugMsg(debugmib.display.asciiOut, "reply CRM_DELETE_SUBS_RSP, result[%d]", err_code); } len = encode_rest_delete_subs_res(&rest_rsp, msg_buf); pps_send_rest_msg(msg_buf, len); return 1; } int pps_handle_crm_rent_charge(_rest_msg_s *rest_req) { _rest_rent_charge_req *pReq = &rest_req->msg.rent_charge; int user_index=0; _account_info user_info; //int flag_log_msisdn = 0; int charge; _prepaid_info *pUsrInfo = NULL; PutLogFunID("pps_handle_crm_rent_charge"); if((logMsgFlag & 0x04) || (logMsgFlag & 0x02)) { DebugMsg(debugmib.display.asciiOut, " TS: %ld.%03d, %s, msisdn[%s]", \ tvnow.tv_sec, tvnow.tv_usec/1000, __FUNCTION__, pReq->msisdn); } strcpy((char *)user_info.number, pReq->msisdn); if(logMsgFlag & 0x08) { if(strstr((char *)user_info.number, logMsisdn)) { //flag_log_msisdn = 1; } } if ((GetAccountPos(&user_info) == FALSE) || ((pUsrInfo = getPrepaidInfo(&user_info)) == NULL)) { DebugMsg(debugmib.display.asciiOut, "%s, msisdn[%s], not found", __FUNCTION__, pReq->msisdn); return 0; } else { charge = pReq->rent_charge; user_index = user_info.head * UNIT_STORE_ACCOUNT + user_info.tail; DebugMsg(debugmib.display.asciiOut, "%s, msisdn[%s], found, charge=%d", __FUNCTION__, pReq->msisdn, charge); } //sync... if(1) { int head = user_index / UNIT_STORE_ACCOUNT; int tail = user_index % UNIT_STORE_ACCOUNT; UpdateAccountCUGStatus(pUsrInfo, 0); UpdateAccountBalance(head, tail, -charge); SendAccountRealSync(user_index,-charge, 0.0, OMC_OCODE_EDIT); SendPeriodicChargeCDR(head,tail, charge, CT_RENT_CHARGE_TYPE0); } return 1; } /*----------------------------------------------------------*/ int pps_rest_recv_proxy() { int loop, retval, portid=0; message_list msgGet; _rest_msg_s rest_msg; _state_data *shmp = (_state_data *) smshm_ptr->state_data; for(loop = 0; loop<5; loop++) { if(iptrGetMessage( &msgGet, REST_PROXY_PORT) <=0 ) return 0; retval = decode_rest_api_msg( msgGet.msgContent, msgGet.msgLength, &rest_msg); if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m Get RestProxy API: type=%d, retval=%d, dst ref=%d\33[0m", rest_msg.msg_type, retval, rest_msg.header.dst_ref); } if(retval <= 0) { continue; } if ((rest_msg.msg_type == REST_QUERY) || (rest_msg.msg_type == REST_TOPUP) || (rest_msg.msg_type == REST_TRANSFER) || (rest_msg.msg_type == REST_ORDER) || (rest_msg.msg_type == REST_FREE_RESOURCE) || (rest_msg.msg_type == REST_CHANNEL) || (rest_msg.msg_type == REST_POINT_QUERY) || (rest_msg.msg_type == REST_POINT_TRANSFER) )// Alepo { portid = rest_msg.header.dst_ref; if ((portid < 0) || (portid >= MAX_FSM_PROCESS)) continue; shmp = (_state_data *) smshm_ptr->state_data; shmp += portid; shmp->process_info.rest_if.recv_cmd = 1; if(rest_msg.msg_type == REST_QUERY) { shmp->process_info.rest_if.result = rest_msg.msg.query_res.result; shmp->process_info.rest_if.error_code = rest_msg.msg.query_res.error_code; if ((rest_msg.msg.query_res.balance & 0x80000000) != 0) { shmp->process_info.rest_if.balance = rest_msg.msg.query_res.balance & 0x7fffffff; shmp->process_info.rest_if.balance = -shmp->process_info.rest_if.balance; } else { shmp->process_info.rest_if.balance = rest_msg.msg.query_res.balance; } shmp->process_info.rest_if.mo_expiry_date = rest_msg.msg.query_res.mo_expiry; shmp->process_info.rest_if.mt_expiry_date = rest_msg.msg.query_res.mt_expiry; } else if(rest_msg.msg_type == REST_TOPUP) { shmp->process_info.rest_if.result = rest_msg.msg.topup_res.result; shmp->process_info.rest_if.error_code = rest_msg.msg.topup_res.error_code; shmp->process_info.rest_if.balance = rest_msg.msg.topup_res.balance; shmp->process_info.rest_if.mo_expiry_date = rest_msg.msg.topup_res.mo_expiry; shmp->process_info.rest_if.mt_expiry_date = rest_msg.msg.topup_res.mt_expiry; } else if(rest_msg.msg_type == REST_TRANSFER) { shmp->process_info.rest_if.result = rest_msg.msg.transfer_rsp.result; shmp->process_info.rest_if.error_code = rest_msg.msg.transfer_rsp.error_code; } else if(rest_msg.msg_type == REST_CHANNEL) { shmp->process_info.rest_if.result = rest_msg.msg.chnl_res.result; shmp->process_info.rest_if.error_code = rest_msg.msg.chnl_res.error_code; shmp->process_info.ppsService.chnl_info.sess_state = rest_msg.msg.chnl_res.sess_state; strcpy(shmp->process_info.ppsService.chnl_info.prompt, rest_msg.msg.chnl_res.prompt); } else if(rest_msg.msg_type == REST_POINT_QUERY) { shmp->process_info.rest_if.result = rest_msg.msg.queryPoint_res.result; shmp->process_info.rest_if.error_code = rest_msg.msg.queryPoint_res.error_code; shmp->process_info.rest_if.unit = rest_msg.msg.queryPoint_res.amount; shmp->process_info.rest_if.balance = rest_msg.msg.queryPoint_res.airtime_amount; } else if(rest_msg.msg_type == REST_POINT_TRANSFER) { shmp->process_info.rest_if.result = rest_msg.msg.queryPoint_res.result; shmp->process_info.rest_if.error_code = rest_msg.msg.queryPoint_res.error_code; } } else// Selfcare { switch (rest_msg.msg_type) { case REST_SEND_AUTHCODE_REQ: pps_handle_send_authcode_req(&rest_msg); break; case REST_QUERY_USERDATA_REQ: pps_handle_query_userdata_req(&rest_msg); break; case REST_BUNDLE_SUBS_REQ: pps_handle_bundle_subs_req(&rest_msg); break; case REST_BUNDLE_USAGE_REQ: pps_handle_bundle_usage_req(&rest_msg); break; case REST_RECHARGE_REQ: pps_handle_recharge_req(&rest_msg); break; case REST_TRANSFER_REQ: pps_handle_transfer_req(&rest_msg); break; case REST_RECHARGE_CARD_REQ: pps_handle_recharge_card_req(&rest_msg); break; case REST_CHECK_BALANCE_REQ: pps_handle_check_balance_req(&rest_msg); break; case REST_QUERY_BALANCE_REQ: pps_handle_query_balance_req(&rest_msg); break; case REST_CRM_SMS_DELIVER_REQ: pps_handle_crm_sms_deliver_req(&rest_msg); break; case REST_CRM_CREATE_ACCT_REQ: pps_handle_crm_create_account_req(&rest_msg); break; case REST_CRM_QUERY_TARIFF_RES: pps_handle_crm_query_tariff_res(&rest_msg); break; case REST_CRM_UPDATE_SUBS_REQ: pps_handle_crm_update_subs(&rest_msg); break; case REST_CRM_DELETE_SUBS_REQ: pps_handle_crm_delete_subs(&rest_msg); break; case REST_CRM_RENT_CHARGE: pps_handle_crm_rent_charge(&rest_msg); break; default: break; } } } return 1; } int pps_rest_query_process(u_short portid) { int retval = 0 ,result; char ussd_data[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); if(shmp->process_info.rest_if.timer ++ > 20*CYCLE_STATE_INTERVAL) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_QUERY_CODE_STR, USSDCODE_TYPE_QUERY, USSDCODE_STAT_ERR_TIMEOUT, 0); #endif return -1; } switch(shmp->process_info.sub_state_2) { case 0: #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_QUERY_CODE_STR, USSDCODE_TYPE_QUERY, USSDCODE_STAT_REQ, 0); #endif pps_send_rest_query_req(portid); shmp->process_info.rest_if.timer = 0; shmp->process_info.rest_if.recv_cmd = 0; shmp->process_info.sub_state_2 = 1; break; case 1: if(shmp->process_info.rest_if.recv_cmd == 0) break; result = shmp->process_info.rest_if.result; if(result == 0) { retval = 1; if(shmp->process_info.rest_if.rest_oc == 1) //recharge and query { char tmp_ussd_data[256]; GetAccountRestInfo(portid, tmp_ussd_data); sprintf(ussd_data, "Refill succeed. %s", tmp_ussd_data); } else { GetAccountRestInfo(portid, ussd_data); } } else { retval = -1; sprintf(ussd_data, "Operation failed, the number %s is not a prepaid subscriber.", shmp->caller_info.number); } if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d , recv query_res, result=%d\33[0m", portid, result); } if(shmp->process_info.rest_if.rest_src == 0) //from USSD { SendPSSREnd(portid, ussd_data); } else if(shmp->process_info.rest_if.rest_src == 1 ) //from SMPP { smppSendMOSM((char *)shmp->caller_info.number, (char *)shmp->origin_info.number, (u_char *)ussd_data, strlen(ussd_data), 0); } else if(shmp->process_info.rest_if.rest_src == 2) //from voice { //SendPSSREnd(portid, ussd_data); } break; default: retval = -1; break; } return retval; } int pps_send_rest_topup_req(u_short portid) { int len = 0; u_char data_flow[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _rest_msg_s rest_msg; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); rest_msg.msg_type = REST_TOPUP; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = portid; strcpy(rest_msg.msg.topup.msisdn, (char *)shmp->caller_info.number); strcpy(rest_msg.msg.topup.username, (char *)shmp->caller_info.number); strcpy(rest_msg.msg.topup.password, (char *)shmp->called_info.number); strcpy(rest_msg.msg.topup.pincode, (char *)shmp->process_info.tmpNumber); len = encode_rest_topup(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); return 1; } int pps_send_rest_channel_req(u_short portid) { int len = 0; u_char data_flow[256]; _state_data *shmp = (_state_data *)smshm_ptr->state_data; _rest_msg_s rest_msg; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); rest_msg.msg_type = REST_CHANNEL; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = portid; strcpy(rest_msg.msg.chnl.msisdn, (char *)shmp->caller_info.number); strcpy(rest_msg.msg.chnl.input, (char *)shmp->process_info.ppsService.chnl_info.input); strncpy(rest_msg.msg.chnl.sc_url, (char *)shmp->process_info.ppsService.chnl_info.scUrl, 127); strncpy(rest_msg.msg.chnl.sess_id, (char *)shmp->process_info.ppsService.chnl_info.sessId, 63); len = encode_rest_channel(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); return 1; } int pps_send_rest_order_req(u_short portid, u32 busicode) { int len = 0; u_char data_flow[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _rest_msg_s rest_msg; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); rest_msg.msg_type = REST_ORDER; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = 0xffff;//portid; rest_msg.msg.order.busicode = busicode;// recharge: 1000, order: 1001, cancel: 1002 rest_msg.msg.order.offer_id = shmp->process_info.rest_if.bundle_plan_id; rest_msg.msg.order.paymethod = shmp->process_info.rest_if.plan_id | (shmp->process_info.rest_if.unit << 8); rest_msg.msg.order.pincode[0] = '\0'; rest_msg.msg.order.callerMsisdn[0] = '\0'; if (shmp->process_info.routing_number[0] != '\0') { strcpy(rest_msg.msg.order.msisdn, (char *)shmp->process_info.routing_number); strcpy(rest_msg.msg.order.payMsisdn, (char *)shmp->caller_info.number); if (busicode == 1000)// recharge airtime, buy for other { strcpy(rest_msg.msg.order.callerMsisdn, (char *)shmp->caller_info.number); } } else { strcpy(rest_msg.msg.order.msisdn, (char *)shmp->caller_info.number); rest_msg.msg.order.payMsisdn[0] = '\0'; } if (shmp->process_info.rest_if.plan_id == 10)// mobile money { strcpy(rest_msg.msg.order.payMsisdn, shmp->process_info.tmpDigits); } rest_msg.msg.order.balance = (u32)shmp->process_info.rest_if.balance; len = encode_rest_order(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); return 1; } int pps_send_rest_free_resource_req(u_short portid) { int len = 0; u_char data_flow[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _rest_msg_s rest_msg; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); rest_msg.msg_type = REST_FREE_RESOURCE; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = 0xffff;//portid; strcpy(rest_msg.msg.free_resource.msisdn, (char *)shmp->caller_info.number); len = encode_rest_free_resource(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); return 1; } int pps_send_rest_download_app_req(u_short portid) { int len = 0; u_char data_flow[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _rest_msg_s rest_msg; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); rest_msg.msg_type = REST_DOWNLOAD_APP; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = 0xffff;//portid; strcpy(rest_msg.msg.downloadApp.msisdn, (char *)shmp->caller_info.number); len = encode_rest_downloadApp(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); return 1; } int pps_send_rest_offer_change_req(u_short portid, u8 flag_opt_out) { int len = 0; u_char data_flow[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _rest_msg_s rest_msg; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); rest_msg.msg_type = REST_OFFER_CHANGE; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = 0xffff;//portid; strcpy(rest_msg.msg.offerChange.msisdn, (char *)shmp->caller_info.number); rest_msg.msg.offerChange.opt_out = flag_opt_out; len = encode_rest_offerChange(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); return 1; } int pps_send_rest_point_query_req(u_short portid) { int len = 0; u_char data_flow[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _rest_msg_s rest_msg; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); rest_msg.msg_type = REST_POINT_QUERY; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = portid; strcpy(rest_msg.msg.queryPoint.msisdn, (char *)shmp->caller_info.number); len = encode_rest_queryPoint(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); return 1; } int pps_send_rest_point_transfer_req(u_short portid, u32 busicode) { int len = 0; u_char data_flow[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _rest_msg_s rest_msg; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); rest_msg.msg_type = REST_POINT_TRANSFER; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = portid;//0xffff; strcpy(rest_msg.msg.transferPoint.msisdn, (char *)shmp->caller_info.number); strcpy(rest_msg.msg.transferPoint.target_msisdn, (char *)shmp->process_info.routing_number); rest_msg.msg.transferPoint.amount = shmp->process_info.rest_if.unit; rest_msg.msg.transferPoint.busicode = busicode; len = encode_rest_transferPoint(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); return 1; } int pps_send_selfcare_topup_req(u_short portid) { int len = 0; u_char data_flow[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _rest_msg_s rest_msg; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); rest_msg.msg_type = REST_UPDATE_RECHARGE_CARD_REQ; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = portid; strcpy(rest_msg.msg.topup.msisdn, (char *)shmp->caller_info.number); strcpy(rest_msg.msg.topup.username, (char *)shmp->caller_info.number); strcpy(rest_msg.msg.topup.password, (char *)shmp->called_info.number); if(1) { rest_msg.msg.topup.optional_flag = 0x03; rest_msg.msg.topup.account_id = 10024; rest_msg.msg.topup.balance = GetAccountBalance(shmp->caller_info.head, shmp->caller_info.tail); } len = encode_rest_topup(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); return 1; } int pps_rest_topup_process(u_short portid) { int retval = 0, /*len, error_input = 0, */result; //u_char data_flow[256], service_type=0; char ussd_data[256];//, ussd_sc[256], ussd_param[256]; //MapComSrv_struct com_data; //MapOprSrv_struct opr_srv; //COSTable *cosTableItem; //struct MapPUSSR_Arg *pussr_arg; //struct MapUSSR_Res *ussr_ack; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); if(shmp->process_info.rest_if.timer ++ > 20*CYCLE_STATE_INTERVAL) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_ERR_TIMEOUT, 0); #endif return -1; } switch(shmp->process_info.sub_state_2) { case 0: pps_send_rest_topup_req(portid); shmp->process_info.rest_if.timer = 0; shmp->process_info.rest_if.recv_cmd = 0; shmp->process_info.sub_state_2 = 1; break; case 1: if(shmp->process_info.rest_if.recv_cmd == 0) break; result = shmp->process_info.rest_if.result; if(result == 0) { //char tmp_ussd_data[256]; if(0) { shmp->process_info.sub_state_2 = 2; shmp->process_info.wait_timer = 0; return 0; } //GetAccountRestInfo(portid, tmp_ussd_data); //sprintf(ussd_data, "You successfully "); sprintf(ussd_data, "%s", getSmsSentenceNative(0, SMS_GPRS_RECHARGE_SUCCESS)); } else { //sprintf(ussd_data, "Operation failed, wrong password, please check and try again!"); sprintf(ussd_data, "%s", getSmsSentenceNative(0, SMS_RECHARGE_FAILED_NO_CARD)); } if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d , recv topup_res, result=%d\33[0m", portid, result); } if( shmp->process_info.rest_if.rest_src == 0) // recharge by USSD { SendPSSREnd(portid, ussd_data); } else if( shmp->process_info.rest_if.rest_src == 1) // recharge by SMPP { smppSendMOSM((char *)shmp->caller_info.number, (char *)shmp->origin_info.number, (u_char *)ussd_data, strlen(ussd_data), 0); } else if( shmp->process_info.rest_if.rest_src == 2) // recharge by Voice { // } retval = 1; break; case 2: if(shmp->process_info.wait_timer ++ >= 1*CYCLE_STATE_INTERVAL) //wait for 1second to send GET { shmp->process_info.rest_if.timer = 0; shmp->process_info.rest_if.recv_cmd = 0; if( shmp->process_info.rest_if.rest_src == 0) // recharge by USSD { shmp->process_info.sub_state = S_MAP_REST_QUERY; } else if( shmp->process_info.rest_if.rest_src == 1) // recharge by SMPP { shmp->process_info.sub_state = S_SMPP_REST_QUERY; } else //recharge by voice shmp->process_info.sub_state = S_MAP_REST_QUERY; shmp->process_info.sub_state_2 = 0; shmp->process_info.wait_timer = 0; shmp->process_info.rest_if.rest_oc = 1; } break; default: retval = -1; break; } return retval; } int pps_send_rest_transfer_req(u_short portid) { int len = 0; u_char data_flow[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _rest_msg_s rest_msg; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); rest_msg.msg_type = REST_TRANSFER; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = portid; strcpy(rest_msg.msg.transfer_req.transferOutMsisdn, (char *)shmp->caller_info.number); strcpy(rest_msg.msg.transfer_req.transferInMsisdn, (char *)shmp->process_info.ppsService.feeTransfer.account.number); rest_msg.msg.transfer_req.amount = shmp->process_info.ppsService.feeTransfer.fee;; len = encode_rest_transfer_req(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); return 1; } int pps_rest_transfer_process(u_short portid) { int retval = 0, result; int op_src = 0; char ussd_data[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); if(shmp->process_info.rest_if.timer ++ > 20*CYCLE_STATE_INTERVAL) { return -1; } switch(shmp->process_info.sub_state_2) { case 0: pps_send_rest_transfer_req(portid); shmp->process_info.rest_if.timer = 0; shmp->process_info.rest_if.recv_cmd = 0; shmp->process_info.sub_state_2 = 1; break; case 1: if(shmp->process_info.rest_if.recv_cmd == 0) break; result = shmp->process_info.rest_if.result; op_src = shmp->process_info.rest_if.rest_src; if(result == 0) { SendTransferSuccessRequest(portid, op_src); } else { sprintf(ussd_data, "Operation failed, please check and try again!"); if(op_src == 0) SendPSSREnd(portid, (char *)ussd_data); else smppSendMsg(shmp->caller_info.number, (u_char *)ussd_data, FeeTransferPosition); } if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d , recv transfer_res, result=%d\33[0m", portid, result); } retval = 1; break; default: retval = -1; break; } return retval; } int RechargeSucceedwithCRM(u_short portid) { int retval = S_IDLE,promo_balance=0; DWORD instance=0; //_account_info tmp_info; _state_data *shmp; COSTable *cosTableItem; if(portid>=MAX_FSM_PROCESS) return 0; PutLogFunID("RechargeRequestProc"); shmp=(_state_data *)&smshm_ptr->state_data; shmp += portid; retval = shmp->process_info.state; UpdateBalanceForRecharge(&shmp->caller_info, shmp->process_info.rest_if.balance); SendRechargeCDR( portid, CT_RECHARGE_SUCCESS, shmp->process_info.rest_if.balance); if(T_FRESH == GetAccountStatus(&shmp->caller_info) ) { UpdateAccountFirstUsedDate(shmp->caller_info.head, shmp->caller_info.tail); } UpdateAccountStatus(shmp->caller_info.head, shmp->caller_info.tail, T_NORMAL); UpdateAccountExpiration(shmp->caller_info.head, shmp->caller_info.tail, shmp->process_info.rest_if.balance, shmp->process_info.rest_if.mo_expiry_date); // promotion cosTableItem = &ppsParam.ppsTables.cosTable[shmp->caller_info.cos_id]; if(IsPromotionTime(cosTableItem,tvnow)) { promo_balance = GetPromotionAmount(cosTableItem,shmp->process_info.rest_if.balance); if(promo_balance !=0) { shmp->cdr_info.answertime = tvnow.tv_sec + 1; UpdateAccountPromotionBalance(shmp->caller_info.head, shmp->caller_info.tail, (float)promo_balance); UpdateAccountPromotionExpiryDay( shmp->caller_info.head, shmp->caller_info.tail, GetPromotionDay(cosTableItem,shmp->process_info.rest_if.balance) ); SendRechargeCDR( portid, CT_RECHARGE_SUCCESS, GetPromotionAmount(cosTableItem,shmp->process_info.rest_if.balance)); } } instance = shmp->caller_info.head * UNIT_STORE_ACCOUNT + shmp->caller_info.tail; ResetAccountRechargeFail(shmp->caller_info.head, shmp->caller_info.tail); resetCMBTimes(&shmp->caller_info); SendAccountRealSync(instance,shmp->process_info.rest_if.balance,promo_balance,OMC_OCODE_EDIT); if(cosTableItem->smsNotificationInquiry[0].smsNotificationWhenRecharge) { if(shmp->process_info.serviceType == SRV_RECHARGE_ONE_INPUT) SendAccountInfoBySMPP(&shmp->caller_info, ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); else SendAccountInfoBySMPP(&shmp->caller_info, ppsParam.ppsTables.serviceNumber[ScratchCardRechargeNumberPosition].number); } return retval; } int pps_bundle_plan_process(u_short portid) { char ussd_data[1024]; int retval = 0, result=0; int key_input; //int cos_bundle_control=0; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); if(shmp->process_info.funnel ++ > 50*CYCLE_STATE_INTERVAL) { return -1; } switch(shmp->process_info.sub_state_2 ) { case 0: subscribe_bundle_plan(shmp, shmp->process_info.tmpDigits, 1, ussd_data); ussd_data[160] = 0; if(strlen(ussd_data) <= 160) { if(1) { SendPSSREnd(portid, ussd_data); retval = 1; } else { SendUSSDRequest(portid, ussd_data); shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; retval = 0; } } break; case 1: retval = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(retval >= 1) { subscribe_bundle_plan(shmp, shmp->process_info.tmpDigits, 1, ussd_data); ussd_data[160] = 0; SendPSSREnd(portid, ussd_data); } break; case 2: result = ocs_bundle_plan_query(shmp, shmp->process_info.tmpDigits, 1, ussd_data); ussd_data[160] = 0; if(1) //if(result == 0) { SendPSSREnd(portid, ussd_data); retval = 1; } else { SendUSSDRequest(portid, ussd_data); shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; retval = 0; } break; case 5://send sub-menu of bundle plan //cos_bundle_control = get_cos_bundle_control(shmp->caller_info.cos_id); if(shmp->process_info.serviceKey == 6)// data plan only sprintf(ussd_data, "%s", getSmsSentenceNative(0,SMS_BUNDLE_PLAN_USSD_MENU)); else sprintf(ussd_data, "%s", getSmsSentenceNative(0,SMS_BUNDLE_PLAN_USSD_MENU1)); if(shmp->process_info.serviceInput ++ > 3) { SendPSSRResponse(portid); return 1; } SendUSSDRequest(portid, ussd_data); shmp->process_info.sub_state_2 = 6; shmp->process_info.funnel = 0; break; case 6: result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { shmp->process_info.sub_state_2 = 5; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { shmp->process_info.sub_state_2 = 5; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1: shmp->process_info.sub_state_2 = 7; //inquiry break; case 2: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 8; //subscribe break; case 0: default: SendPSSRResponse(portid); retval = 1; break; } } } else if(result == -1) { SendPSSRResponse(portid); retval = 1; } break; case 7: result = ocs_bundle_plan_query(shmp, shmp->process_info.tmpDigits, 1, ussd_data); ussd_data[160] = 0; if(result == 0) { SendPSSREnd(portid, ussd_data); retval = 1; } else { sprintf(ussd_data, "%s", getSmsSentenceNative(0,SMS_BUNDLE_PLAN_NOT_APPLIED)); SendPSSREnd(portid, ussd_data); retval = 1; } break; case 8:// ussd adaptor enter here if(shmp->process_info.serviceInput ++ > 3) { SendPSSRResponse(portid); return 1; } subscribe_bundle_plan_query_info(shmp, 0, 2, ussd_data); SendUSSDRequest(portid, ussd_data); shmp->process_info.sub_state_2 = 9; shmp->process_info.funnel = 0; break; case 9: result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 2) { shmp->process_info.sub_state_2 = 8; shmp->process_info.funnel = 0; break; } if (0)//(pps_get_adaptor_flag()) {/* pps_send_rest_order_req(portid);// send bundle subs req shmp->process_info.funnel = 0; shmp->process_info.rest_if.timer = 0; shmp->process_info.rest_if.recv_cmd = 0; shmp->process_info.sub_state_2 = 11;*/ } else { result = subscribe_bundle_plan(shmp, shmp->process_info.tmpDigits, 2, ussd_data); if(result == 1) { SendPSSREnd(portid, ussd_data); retval = 1; } else { shmp->process_info.sub_state_2 = 8; shmp->process_info.funnel = 0; } } } else if(result == -1) { SendPSSRResponse(portid); retval = 1; } break; /*case 11: if(shmp->process_info.rest_if.recv_cmd == 0) break; result = shmp->process_info.rest_if.result; if(result == 0) { //char tmp_ussd_data[256]; if(0) { shmp->process_info.sub_state_2 = 2; shmp->process_info.wait_timer = 0; return 0; } //GetAccountRestInfo(portid, tmp_ussd_data); //sprintf(ussd_data, "You successfully "); sprintf(ussd_data, "%s", getSmsSentenceNative(0, SMS_GPRS_RECHARGE_SUCCESS)); } else { //sprintf(ussd_data, "Operation failed, wrong password, please check and try again!"); sprintf(ussd_data, "%s", getSmsSentenceNative(0, SMS_RECHARGE_FAILED_NO_CARD)); } if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d , recv topup_res, result=%d\33[0m", portid, result); } //if( shmp->process_info.rest_if.rest_src == 0) // recharge by USSD //{ SendPSSREnd(portid, ussd_data); //} break;*/ } return retval; } int pps_send_query_tariff_req(u_short portid) { char prefix[32], areaName[32] = ""; int service_type = 1; /*1=mo call, 2=sms, 3=data */ int len = 0; u_char data_flow[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _rest_msg_s rest_msg; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); rest_msg.msg_type = REST_CRM_QUERY_TARIFF_REQ; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = portid; if(shmp->context_info.callType == CT_MO_CALL || shmp->context_info.callType == CT_MF_CALL) service_type = 1; else if(shmp->context_info.callType == CT_MT_CALL) service_type = 1; else if(shmp->context_info.callType == CT_MO_SM) service_type = 3; else//data service_type = 2; rest_msg.msg.query_tariff.service_type = service_type; if(service_type != 2) { if(ocs_get_charge_prefix( (char *)shmp->charge_info.number, prefix, areaName, &shmp->process_info.tariff.call_type) == 0) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d , ocs_get_charge_prefix() failed, charge_number=%s \33[0m", portid, shmp->charge_info.number); } return 0; } strncpy(shmp->process_info.ppsService.areaName, areaName, 31); } else {//CRM bug, data billing must take a area_code... memcpy(prefix, shmp->caller_info.number, 5); prefix[5] = 0; } if(service_type == 1) shmp->process_info.call_type = shmp->process_info.tariff.call_type; #ifdef OCS_USE_REDIS_DB// get tariff and bundle if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "[%04d], prefix[%s] caller=%s charge_number=%s, srv_type=%d", portid, prefix, shmp->caller_info.number, shmp->charge_info.number, service_type); } RedisGetTariffInfo(portid, (char *)shmp->caller_info.number, service_type, prefix); return 1; #endif shmp->process_info.rest_if.query_tariff_status = 1; //wait for result strcpy(rest_msg.msg.query_tariff.msisdn, (char *)shmp->caller_info.number); strcpy(rest_msg.msg.query_tariff.called_number, prefix); len = encode_rest_query_tariff(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d , ocs_get_charge_prefix() caller=%s charge_number=%s , srv_type=%d\33[0m", portid, shmp->caller_info.number, shmp->charge_info.number, service_type); } return 1; } int pps_send_update_plan_value_req(u_short portid) { int service_type = 1; /*1=mo call, 2=sms, 3=data */ int len = 0; u_char data_flow[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; _rest_msg_s rest_msg; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); rest_msg.msg_type = REST_CRM_UPDATE_PLAN_INFO_REQ; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = portid; if(shmp->context_info.callType == CT_MO_CALL || shmp->context_info.callType == CT_MF_CALL) service_type = 1; else if(shmp->context_info.callType == CT_MT_CALL) service_type = 1; else if(shmp->context_info.callType == CT_MO_SM) service_type = 3; else//data service_type = 2; /* if(shmp->process_info.call_type == CT_MO_CALL || shmp->process_info.call_type == CT_MF_CALL) service_type = 0; else if(shmp->process_info.call_type == CT_MT_CALL) service_type = 1; else if(shmp->process_info.call_type == CT_MO_SM) service_type = 3; else//data service_type = 2; */ #ifdef OCS_USE_REDIS_DB if ((shmp->process_info.rest_if.plan_value_add_this_time & 0x8000000000000000) == 0)// not refund { RedisUpdateUsedBundle((char *)shmp->caller_info.number, service_type, shmp->process_info.rest_if.bundle_plan_id, shmp->process_info.rest_if.plan_value_add_this_time); } #endif strcpy(rest_msg.msg.update_plan_info.msisdn, (char *)shmp->caller_info.number); rest_msg.msg.update_plan_info.service_type = service_type; rest_msg.msg.update_plan_info.account_id = GetAccountID(&shmp->caller_info); rest_msg.msg.update_plan_info.plan_id = shmp->process_info.rest_if.plan_id; rest_msg.msg.update_plan_info.bundle_id = shmp->process_info.rest_if.bundle_plan_id; rest_msg.msg.update_plan_info.plan_total_value = shmp->process_info.rest_if.total_plan_value; rest_msg.msg.update_plan_info.plan_used_value = shmp->process_info.rest_if.used_plan_value; rest_msg.msg.update_plan_info.sess_update_times = shmp->process_info.rest_if.sess_update_times++; rest_msg.msg.update_plan_info.this_time_add_value = shmp->process_info.rest_if.plan_value_add_this_time; if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid[%04d], update_plan_value_req() caller=%s, ID[%d], total-used[%llu-%llu], this[0x%llx], srv_type=%d\33[0m", portid, shmp->caller_info.number, shmp->process_info.rest_if.bundle_plan_id, shmp->process_info.rest_if.total_plan_value, shmp->process_info.rest_if.used_plan_value, shmp->process_info.rest_if.plan_value_add_this_time, service_type); } len = encode_rest_update_plan_info(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); return 1; } int query_tariff_test(u_char call_type) { int portid = AssignProcID(0); _state_data *shmp = (_state_data *) smshm_ptr->state_data; shmp += (portid); sprintf((char *)shmp->caller_info.number, "%s", "672350004"); sprintf((char *)shmp->called_info.number, "%s", "008675512345678"); shmp->process_info.call_type = call_type; shmp->process_info.state = S_CRM_QUERY_TARIFF_TEST; pps_send_query_tariff_req(portid); return 1; } int pps_crm_query_tariff_test_proc(u_short portid) { int retval = 0; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); if(shmp->process_info.funnel ++ > SSHORT_DELAY_TIMER) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d wait query tariff result timeout\33[0m", portid); } return -1; } if(shmp->process_info.rest_if.query_tariff_status == 2) { retval = 1; } return retval; } void pps_send_update_subs_status_to_crm(/*int head, int tail*/_prepaid_info *user_ptr, int update_flag) { int len = 0; u_char data_flow[256]; _rest_msg_s rest_msg; //_prepaid_info *user_ptr=NULL; char msisdn[32]; //user_ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; rest_msg.msg_type = REST_CRM_UPDATE_SUBS_REQ; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = 0xffff; if (update_flag == 1) rest_msg.msg.update_subs.optional_flag = 0x01; else if (update_flag == 2) rest_msg.msg.update_subs.optional_flag = 0x04 | 0x08; len = user_ptr->msisdn[MAX_MSISDN_BLEN-1]; if(lenMAX_MSISDN_ALEN) { return; } BcdToAscii(msisdn,user_ptr->msisdn,(MAX_MSISDN_BLEN-1)*2); msisdn[len] = 0; strcpy(rest_msg.msg.update_subs.msisdn, msisdn); rest_msg.msg.update_subs.account_id = user_ptr->crm_info.account_id; rest_msg.msg.update_subs.status = user_ptr->status; rest_msg.msg.update_subs.basic_plan_id = user_ptr->crm_info.base_plan_id; rest_msg.msg.update_subs.balance_expiry_date = user_ptr->mo_expiration_date; len = encode_rest_update_subs(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); } /* rent charge to CRM, if succeed then CRM sends payment request to OCS if failed, CRM sends update account status with CUG status (crm_info.vas_cug_state = 1 */ void pps_send_rent_charge_to_crm(int head, int tail) { int len = 0; u_char data_flow[256]; _rest_msg_s rest_msg; _prepaid_info *user_ptr=NULL; char msisdn[32]; user_ptr = &ramshm_ptr->prepaid_data.prepaid_info[head][tail]; rest_msg.msg_type = REST_CRM_RENT_CHARGE; rest_msg.header.dst_ref = 0x0000; rest_msg.header.src_ref = 0xffff; rest_msg.msg.rent_charge.optional_flag = 0x01; len = user_ptr->msisdn[MAX_MSISDN_BLEN-1]; if(lenMAX_MSISDN_ALEN) { return; } BcdToAscii(msisdn,user_ptr->msisdn,(MAX_MSISDN_BLEN-1)*2); msisdn[len] = 0; strcpy(rest_msg.msg.rent_charge.msisdn, msisdn); rest_msg.msg.rent_charge.balance = user_ptr->balance; len = encode_rest_rent_charge(&rest_msg, data_flow); pps_send_rest_msg(data_flow, len); } /*---------------------------------------------------------*/ int ppsMapState(u_short portid) { int retval = 0,len, error_input = 0, result; u_char data_flow[256], service_type=0; char ussd_data[256], ussd_sc[64], ussd_param[256], ussd_param1[256]; MapComSrv_struct com_data; MapOprSrv_struct opr_srv; //COSTable *cosTableItem; struct MapPUSSR_Arg *pussr_arg; struct MapUSSR_Res *ussr_ack; int cos_bundle_control=0; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); shmp->process_info.duration ++; if(shmp->process_info.funnel ++ > USSD_DELAY_TIMER) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report if(pps_get_adaptor_flag()) { if (shmp->process_info.sub_state == S_MAP_RECHARGE_WAIT_PIN) { pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_ERR_TIMEOUT, shmp->process_info.duration); } } #endif if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d ,did: %d, wait pussdr request timeout\33[0m", portid,shmp->context_info.map_did); } ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); return -1; } if(map_get_comdata_struct(&com_data,shmp->context_info.map_did)) { if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\nportid: %d ,did: %d, Get Map com, type: %d @ %ld.%ld", portid,shmp->context_info.map_did, com_data.message_type, tvnow.tv_sec,tvnow.tv_usec); map_com_stof(&com_data,data_flow,0); pps_debug_map_msg(data_flow,0); } if(com_data.message_type != MAP_DELIMITER) { ppsSendUSSDStatistics(shmp); return (retval = 1); } } switch(shmp->process_info.sub_state) { case S_MAP_SEND_OPENRSP: if(shmp->context_info.map_acn == AC_networkUnstructuredSs) { pps_send_map_openrsp(portid, OpenResultAccept); } else { pps_send_map_openrsp(portid,OpenResultRefuse); } shmp->process_info.funnel = 0; shmp->process_info.sub_state = S_MAP_GET_PUSSDR; break; case S_MAP_GET_PUSSDR: if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) { break; } if((data_flow[9] != ProcUnstrctSSReq) || data_flow[1]<14) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d ,did: %d, wait PSSDR but %d received\33[0m", portid,shmp->context_info.map_did,data_flow[9]); } ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); return -1; } if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\nportid: %d ,did: %d, Get Map opr,type:<%d>, PUSSR ", portid,shmp->context_info.map_did, data_flow[9]); pps_debug_map_msg(data_flow,0); } opr_srv.version = shmp->context_info.map_acn_ver; opr_srv.message_type = data_flow[9]; opr_srv.message_flag = data_flow[10]; opr_srv.port_id = portid; opr_srv.dialogue_id = shmp->context_info.map_did; if(extract_mapparam(&opr_srv, data_flow[9], data_flow[10], data_flow[14]*256+data_flow[15], &data_flow[16])<=0) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31mportid: %d ,did: %d, decode PUSSR failed \33[0m", portid,shmp->context_info.map_did); } ppsSendUSSDStatistics(shmp); return -1; } shmp->context_info.invoke_id = data_flow[11]; //opr_srv.invoke_id; pussr_arg = &opr_srv.msg_list.pussr_arg; if(pussr_arg->param_flag != 0x01) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31mportid: %d ,did: %d, decode PUSSR failed \33[0m", portid,shmp->context_info.map_did); } ppsSendUSSDStatistics(shmp); return -1; } switch(pussr_arg->ussd_arg.ussd_scheme & 0x0f) { case 0x00: case 0x0f: /* 7bit */ smppDecodeSM((char *)pussr_arg->ussd_arg.ussd_string.ussd_data, ussd_data, pussr_arg->ussd_arg.ussd_string.string_len); break; case 0x04: /* 8bit */ default: memcpy(ussd_data, pussr_arg->ussd_arg.ussd_string.ussd_data, pussr_arg->ussd_arg.ussd_string.string_len); break; } if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\nportid: %d ,did: %d, USSD data: \r\n\%s ", portid,shmp->context_info.map_did, ussd_data); } len = pussr_arg->ussd_arg.msisdn[0]; if(len<3 || len>11) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31mportid: %d ,did: %d, decode PUSSR failed, error MSISDN length: %d\33[0m", portid,shmp->context_info.map_did,len); } shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; return retval; } ppsBcdToAsciiR(shmp->caller_info.number, &pussr_arg->ussd_arg.msisdn[2], (len-1)*2); StringCut((char *)shmp->caller_info.number, 'F'); GetAccountPos(&shmp->caller_info); memset(shmp->cdr_info.caller,0xFF,8); memcpy(shmp->cdr_info.caller,&pussr_arg->ussd_arg.msisdn[2],(len-1)); memset(shmp->caller_info.IMSI, 0xFF, 8); if(logMsgFlag & 0x08) { if(strstr((char *)shmp->caller_info.number, logMsisdn)){ shmp->process_info.logMsisdn = 0x01; } } if(pps_get_adaptor_flag()) { shmp->caller_info.cos_id = 0; shmp->caller_info.cug_id = 0; shmp->caller_info.head = 0; shmp->caller_info.tail = 0; } else { if(shmp->caller_info.headcaller_info.cos_id = GetAccountCosID(&shmp->caller_info); shmp->caller_info.cug_id = GetAccountCUG(&shmp->caller_info); shmp->caller_info.status = GetAccountStatus(&shmp->caller_info); if(shmp->caller_info.status == T_BLACKLIST || shmp->caller_info.status == T_RELEASED) { shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; return retval; } } else { /* send error info */ if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31mportid: %d ,did: %d, PUSSR, msisdn=%s not prepaid subs. \33[0m", portid,shmp->context_info.map_did, shmp->caller_info.number); } shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; shmp->process_info.u_error = CAP_ERR_MISSING_CUSTOMER_RECORD; return retval; } } memset(ussd_sc, 0x00, 24); memset(ussd_param, 0x00, 24); memset(ussd_param1, 0x00, 24); ppsGetUssdParameter(ussd_data, ussd_sc, ussd_param, ussd_param1); ussd_sc[23] = 0; ussd_param[23] = 0; ussd_param1[23] = 0; strcpy((char *)shmp->called_info.number, ussd_sc); service_type = GetUssdServiceType(shmp); if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[32mportid: %d ,USSD Service Code:<%s>, service type=%d , Param: %s \33[0m", portid, ussd_sc, service_type, ussd_param); } shmp->process_info.funnel = 0; shmp->process_info.serviceKey = 0; shmp->process_info.sub_state_2 = 0; memset(shmp->process_info.tmpDigits, 0x00, MAX_ASCII_NUMBER_LEN); if(strlen(ussd_param) < MAX_ASCII_NUMBER_LEN) strcpy(shmp->process_info.tmpDigits, ussd_param); else { memcpy(shmp->process_info.tmpDigits, ussd_param, MAX_ASCII_NUMBER_LEN - 1); } switch(service_type) { case SRV_INQUIRY: shmp->process_info.serviceKey = 1; UssdInquiryProcess(portid); break; case SRV_SCRATCH_CARD_RECHARGE: case SRV_RECHARGE_2TYPES: len = strlen(ussd_param); if(len>=8)// (len>=10) { memset(shmp->cdr_info.called,0xFF,10); ppsAsciiToBcdR(shmp->cdr_info.called, ussd_param, (len+1)/2*2); if(len%2) shmp->cdr_info.called[(len+1)/2] |= 0xF0; strcpy((char *)shmp->called_info.number, ussd_param); strcpy((char *)shmp->process_info.tmpNumber, ussd_param1); if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[32mportid: %d ,did: %d, PUSSR, msisdn=%s [ all-in-one input ]. \33[0m", portid,shmp->context_info.map_did, shmp->caller_info.number); DebugMsg(debugmib.display.asciiOut, "\n\33[32 Service code:%s, recharge card password:%s. \33[0m",ussd_sc,ussd_param); } shmp->process_info.funnel = 0; shmp->process_info.sub_state = S_MAP_CHECK_USSD_INPUT_CARD_VALIDITY; } else { SendUSSDRechargeRequest(portid); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state = S_MAP_RECHARGE_WAIT_PIN; shmp->process_info.serviceKey = 2; } #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_REQ, 0); #endif break; case SRV_FEE_TRANSFER: if(!pps_get_adaptor_flag()) { if(shmp->caller_info.status == T_FRESH || shmp->caller_info.status == T_SUSPEND) { shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; return retval; } } if(strlen(ussd_param) > 2 && strlen(ussd_param1)>0) { shmp->process_info.ussd_transfer_one_input_flag = 1; strcpy((char *)shmp->process_info.ppsService.feeTransfer.account.number, ussd_param); shmp->process_info.ppsService.feeTransfer.fee = atoi(ussd_param1); if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[32mportid: %d ,did: %d, PUSSR, msisdn=%s [ ussd balance transfer all-in-one ]. \33[0m", portid,shmp->context_info.map_did, shmp->caller_info.number); DebugMsg(debugmib.display.asciiOut, "\n\33[32 received number :%s, balance to be transferred:%d. \33[0m",ussd_param, shmp->process_info.ppsService.feeTransfer.fee); } } else shmp->process_info.ussd_transfer_one_input_flag = 0; shmp->process_info.sub_state = S_MAP_FEE_TRANSFER; shmp->process_info.serviceKey = 3; break; case SRV_CALL_ME_BACK: clearCMBInfo(portid); shmp->process_info.sub_state = S_MAP_CALL_ME_BACK; shmp->process_info.serviceKey = 4; break; case SRV_TELL_ME_NUMBER: shmp->process_info.sub_state = S_MAP_TELL_ME_NUMBER; shmp->process_info.serviceKey = 5; break; case SRV_FAVORITE_NUMBER: shmp->process_info.sub_state = S_MAP_FAVORITE_NUMBER; shmp->process_info.serviceKey = 6; break; case SRV_BUNDLE_PLAN: if(shmp->caller_info.status == T_FRESH || shmp->caller_info.status == T_SUSPEND) { shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; return retval; } if(1) { char called_buf[32]; strcpy((char *)shmp->called_info.number, ussd_sc); len = strlen((char *)shmp->called_info.number); strcpy(called_buf, (char *)shmp->called_info.number); if(len %2 ==1){ strcat(called_buf,"F"); len ++; } strcat(called_buf,"FF"); ppsAsciiToBcdR(shmp->cdr_info.called, called_buf, len+2); } shmp->process_info.sub_state = S_MAP_BUNDLE_PLAN; shmp->process_info.serviceKey = 7; break; case SRV_BUNDLE_QUERY: if(shmp->caller_info.status == T_FRESH || shmp->caller_info.status == T_SUSPEND) { shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; return retval; } shmp->process_info.sub_state = S_MAP_BUNDLE_PLAN; shmp->process_info.sub_state_2 = 2; shmp->process_info.serviceKey = 8; break; case SRV_CALL_HOTLINE: default: if(pps_get_adaptor_flag()) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ if (match_channel_info(ussd_sc, shmp->process_info.ppsService.chnl_info.scUrl) > 0) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(ussd_sc, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_REQ, 0); #endif shmp->process_info.sub_state = S_MAP_THIRD_PARTY_CHANNEL; shmp->process_info.sub_state_2 = 1; break; } else if (memcmp(ussd_sc, "117", 3) == 0) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_REQ, 0); #endif shmp->process_info.sub_state = S_MAP_THIRD_PARTY_HOTLINE; shmp->process_info.sub_state_2 = 1; break; } else #endif { shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; return retval; } } cos_bundle_control = get_cos_bundle_control(shmp->caller_info.cos_id); if(cos_bundle_control == 1)// data plan only SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_USSD_MENU)); else SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_USSD_MENU1)); shmp->process_info.sub_state = S_MAP_GET_USSDACK; break; } break; case S_MAP_GET_USSDACK: if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) { break; } if((data_flow[9] != UnstrctSSReq) || data_flow[1]<14) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d ,did: %d, wait USSDR_ACK but %d received\33[0m", portid,shmp->context_info.map_did,data_flow[9]); } ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); return -1; } if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\nportid: %d ,did: %d, Get Map opr,type:<%d>, USSR ", portid,shmp->context_info.map_did, data_flow[9]); pps_debug_map_msg(data_flow,0); } opr_srv.version = shmp->context_info.acn_ver; opr_srv.message_type = data_flow[9]; opr_srv.message_flag = data_flow[10]; opr_srv.port_id = portid; opr_srv.dialogue_id = shmp->context_info.map_did; if(extract_mapparam(&opr_srv, data_flow[9], data_flow[10], data_flow[14]*256+data_flow[15], &data_flow[16])<=0) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31mportid: %d ,did: %d, decode USSR_ACK failed \33[0m", portid,shmp->context_info.map_did); } ppsSendUSSDStatistics(shmp); return -1; } ussr_ack = &opr_srv.msg_list.ussr_res; if(ussr_ack->param_flag != 0x01) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31mportid: %d ,did: %d, USSR error received \33[0m", portid,shmp->context_info.map_did); } ppsSendUSSDStatistics(shmp); return -1; } switch(ussr_ack->ussd_res.ussd_scheme & 0x0f) { case 0x00: case 0x0f: /* 7bit */ smppDecodeSM((char *)ussr_ack->ussd_res.ussd_string.ussd_data, ussd_data, ussr_ack->ussd_res.ussd_string.string_len); break; case 0x04: /* 8bit */ default: memcpy(ussd_data, ussr_ack->ussd_res.ussd_string.ussd_data, ussr_ack->ussd_res.ussd_string.string_len); break; } if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\nportid: %d ,did: %d, USSD data: \r\n\%s ", portid,shmp->context_info.map_did, ussd_data); } cos_bundle_control = get_cos_bundle_control(shmp->caller_info.cos_id); if(ussr_ack->ussd_res.ussd_string.string_len == 1) { unsigned char key; if(ussd_data[0]>=0x30 && ussd_data[0]<=0x39) ussd_data[0] -= 0x30; /* 0-9 */ else if(ussd_data[0]>=0x61 ) ussd_data[0] -= 0x61; /* a- z */ else if(ussd_data[0] >=0x41 ) ussd_data[0] -= 0x41; /* A-Z */ /* change ascii to digits */ key = GetUssdServiceKey(ussd_data[0]); switch(key) { case USSD_OC_INQUIRY: UssdInquiryProcess(portid); break; case USSD_OC_RECHARGE: SendUSSDRechargeRequest(portid); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state = S_MAP_RECHARGE_WAIT_PIN; shmp->process_info.serviceKey = 2; break; case USSD_OC_FEE_TRANSFER: if(shmp->caller_info.status == T_FRESH || shmp->caller_info.status == T_SUSPEND) { shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; return retval; } shmp->process_info.sub_state = S_MAP_FEE_TRANSFER; shmp->process_info.serviceKey = 3; break; case USSD_OC_CALL_ME_BACK: clearCMBInfo(portid); shmp->process_info.sub_state = S_MAP_CALL_ME_BACK; shmp->process_info.serviceKey = 4; break; case USSD_OC_TELL_ME_NUMBER: shmp->process_info.sub_state = S_MAP_TELL_ME_NUMBER; shmp->process_info.serviceKey = 5; break; case USSD_OC_FRIEND_FAMILY_QUERY: shmp->process_info.sub_state = S_MAP_FAVORITE_NUMBER; shmp->process_info.sub_state_2 = 0; shmp->process_info.serviceKey = 6; break; case USSD_OC_EXIT: case USSD_OC_HOTLINE: shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; shmp->process_info.serviceKey = 7; break; case USSD_OC_BUNDLE_PLAN: case USSD_OC_BUNDLE_PLAN_ALL: if(shmp->caller_info.status == T_FRESH || shmp->caller_info.status == T_SUSPEND) { shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; shmp->process_info.u_error = _PPS_ERR_SERVICE_NOT_APPLIED; return retval; } if((cos_bundle_control == 1) && (key == USSD_OC_BUNDLE_PLAN_ALL))// user has data plan only, not allow to request bundle plan! { error_input = 1; break; } if(1) { char called_buf[32]; strcpy((char *)shmp->called_info.number, ussd_sc); len = strlen((char *)shmp->called_info.number); strcpy(called_buf, (char *)shmp->called_info.number); if(len %2 ==1){ strcat(called_buf,"F"); len ++; } strcat(called_buf,"FF"); ppsAsciiToBcdR(shmp->cdr_info.called, called_buf, len+2); } shmp->process_info.sub_state = S_MAP_BUNDLE_PLAN; shmp->process_info.sub_state_2 = 5; if(key == USSD_OC_BUNDLE_PLAN_ALL) shmp->process_info.serviceKey = 7; else shmp->process_info.serviceKey = 6; break; default: error_input = 1; break; } } else { error_input = 1; } /* error input */ if(error_input) { if(shmp->process_info.serviceInput++>=3) { shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; } else { if (cos_bundle_control == 0)// user has bundle plan, no suitable sentance, so has to repeat it { SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_USSD_MENU1));// repeat this menu } else { SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_USSD_ERROR_INPUT)); } } } shmp->process_info.funnel = 0; break; case S_MAP_RECHARGE_WAIT_PIN: if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) { break; } if((data_flow[9] != UnstrctSSReq) || data_flow[1]<14) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_ERR_SYSTEM, shmp->process_info.duration); #endif if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d ,did: %d, wait USSDR_ACK but %d received\33[0m", portid,shmp->context_info.map_did,data_flow[9]); } ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); return -1; } if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\nportid: %d ,did: %d, Get Map opr,type:<%d>, USSR ", portid,shmp->context_info.map_did, data_flow[9]); pps_debug_map_msg(data_flow,0); } opr_srv.version = shmp->context_info.acn_ver; opr_srv.message_type = data_flow[9]; opr_srv.message_flag = data_flow[10]; opr_srv.port_id = portid; opr_srv.dialogue_id = shmp->context_info.map_did; if(extract_mapparam(&opr_srv, data_flow[9], data_flow[10], data_flow[14]*256+data_flow[15], &data_flow[16])<=0) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_ERR_MSG, shmp->process_info.duration); #endif if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31mportid: %d ,did: %d, decode USSR_ACK failed \33[0m", portid,shmp->context_info.map_did); } ppsSendUSSDStatistics(shmp); return -1; } ussr_ack = &opr_srv.msg_list.ussr_res; if(ussr_ack->param_flag != 0x01) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_ERR_MSG, shmp->process_info.duration); #endif if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31mportid: %d ,did: %d, USSR error received \33[0m", portid,shmp->context_info.map_did); } return -1; } switch(ussr_ack->ussd_res.ussd_scheme & 0x0f) { case 0x00: case 0x0f: /* 7bit */ smppDecodeSM((char *)ussr_ack->ussd_res.ussd_string.ussd_data, ussd_data, ussr_ack->ussd_res.ussd_string.string_len); break; case 0x04: /* 8bit */ default: memcpy(ussd_data, ussr_ack->ussd_res.ussd_string.ussd_data, ussr_ack->ussd_res.ussd_string.string_len); break; } if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\nportid: %d ,did: %d, USSD data: %s", portid,shmp->context_info.map_did, ussd_data); } len = strlen(ussd_data); if(len>16) { ussd_data[16] = 0; len = 16; } memset(shmp->cdr_info.called,0xFF,10); ppsAsciiToBcdR(shmp->cdr_info.called, ussd_data, (len+1)/2*2); if(len%2) shmp->cdr_info.called[(strlen(ussd_data)+1)/2] |= 0xF0; strcpy((char *)shmp->called_info.number, ussd_data); shmp->process_info.funnel = 0; shmp->process_info.sub_state = S_MAP_CHECK_USSD_INPUT_CARD_VALIDITY; break; case S_MAP_CHECK_USSD_INPUT_CARD_VALIDITY: if(UseExternalVC()) { shmp->process_info.sub_state_2 = 0; shmp->process_info.sub_state = S_MAP_USSD_CHECK_CARD_DATA_RCM; return retval; } if(OCS_with_external_CRM()) { shmp->process_info.sub_state_2 = 0; shmp->process_info.sub_state = S_MAP_USSD_CHECK_CARD_DATA_CRM; return retval; } if(pps_get_adaptor_flag()) { shmp->process_info.sub_state = S_MAP_REST_TOPUP; shmp->process_info.sub_state_2 = 0; return retval; } if(CheckWetherValidRechargeCard(portid,shmp->called_info.number, &result)==0) { if(result == 5 ) { shmp->process_info.u_error = 0xee; shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; } else { shmp->process_info.sub_state = S_MAP_USSD_INPUT_CARD_PWD_AGAIN; } return retval; } RechargeRequestProc(portid); SendUSSDRechargeSuccessInfo(portid); //shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK_SEND_USSN; if(1) { ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); shmp->process_info.sub_state = S_IDLE; retval = 1; } break; case S_MAP_USSD_INPUT_CARD_PWD_AGAIN: if(shmp->process_info.serviceInput++>3) { shmp->process_info.u_error = 0xee; shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; return retval; } SendUSSDRechargeRequestAgain(portid); shmp->process_info.sub_state = S_MAP_RECHARGE_WAIT_PIN; break; case S_MAP_USSD_CHECK_CARD_DATA_RCM: switch(shmp->process_info.sub_state_2 ) { case 0: send_scf_update_card_data(portid); shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; shmp->process_info.update_card_ack = 0; break; case 1: if(!shmp->process_info.update_card_ack) { return retval; } if(shmp->process_info.funnel>SSHORT_DELAY_TIMER) { shmp->process_info.u_error = 0xee; shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; return retval; } if(shmp->process_info.update_card_result != OC_RESULT_OK) { RechargeFailedUpdateAccountData(portid); shmp->process_info.sub_state = S_MAP_USSD_INPUT_CARD_PWD_AGAIN; return retval; } RechargeRequestProc(portid); SendUSSDRechargeSuccessInfo(portid); shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK_SEND_USSN; break; default: shmp->process_info.u_error = 0xee; shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; break; } break; case S_MAP_USSD_CHECK_CARD_DATA_CRM: switch(shmp->process_info.sub_state_2 ) { case 0: pps_send_selfcare_topup_req(portid); shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; shmp->process_info.rest_if.recv_cmd = 0; break; case 1: if(shmp->process_info.rest_if.recv_cmd == 0) { return retval; } if(shmp->process_info.funnel>SSHORT_DELAY_TIMER) { shmp->process_info.u_error = 0xee; shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; return retval; } if(shmp->process_info.rest_if.result) { RechargeFailedUpdateAccountData(portid); shmp->process_info.sub_state = S_MAP_USSD_INPUT_CARD_PWD_AGAIN; return retval; } RechargeSucceedwithCRM(portid); SendUSSDRechargeSuccessInfo(portid); shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK_SEND_USSN; break; default: shmp->process_info.u_error = 0xee; shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; break; } break; case S_MAP_SEND_PUSSR_ACK: SendPSSRResponse(portid); ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); shmp->process_info.sub_state = S_IDLE; return 1; break; case S_MAP_SEND_PUSSR_ACK_SEND_USSN: if(!map_get_oprdata(data_flow,shmp->context_info.map_did)) { break; } if((data_flow[9] != UnstrctSSNoti) || data_flow[1]<10) { if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d ,did: %d, wait USSDN_ACK but %d received\33[0m", portid,shmp->context_info.map_did,data_flow[9]); } ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); return -1; } if((logMsgFlag == 0xff) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\nportid: %d ,did: %d, Get Map opr < USSN_ACK > ", portid,shmp->context_info.map_did); pps_debug_map_msg(data_flow,0); } SendPSSRResponse(portid); ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); shmp->process_info.sub_state = S_IDLE; shmp->process_info.funnel = 0; return 1; break; case S_MAP_WAIT_USSN_ACK: ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); shmp->process_info.sub_state = S_IDLE; retval = 1; break; case S_MAP_FEE_TRANSFER: result = transferAccountUSSDProc(portid); switch(result) { case SERVICE_KEEP_STATE: break; case SERVICE_RETURN_TO_PARENT: SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_USSD_MENU)); shmp->process_info.funnel = 0; shmp->process_info.sub_state = S_MAP_GET_USSDACK; break; case SERVICE_EXIT_PPS: default: shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; break; } break; case S_MAP_CALL_ME_BACK: result = callMebackUSSDProc(portid); switch(result) { case SERVICE_KEEP_STATE: break; case SERVICE_RETURN_TO_PARENT: SendUSSDRequest(portid, (char *)getSmsSentenceNative(0,SMS_USSD_MENU)); shmp->process_info.funnel = 0; shmp->process_info.sub_state = S_MAP_GET_USSDACK; break; case SERVICE_EXIT_PPS: default: shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; break; } break; case S_MAP_TELL_ME_NUMBER: SendUSSDTellMeNumberInfo(portid); shmp->process_info.sub_state = S_MAP_WAIT_USSN_ACK; break; case S_MAP_FAVORITE_NUMBER: result = favoriteNumberUssdProc(portid); switch(result) { case SERVICE_KEEP_STATE: break; case SERVICE_EXIT_PPS: shmp->process_info.sub_state = S_MAP_WAIT_USSN_ACK; break; case SERVICE_RETURN_TO_PARENT: default: shmp->process_info.sub_state = S_MAP_SEND_PUSSR_ACK; break; } break; case S_MAP_REST_QUERY: retval = pps_rest_query_process(portid); if(retval != 0) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_QUERY_CODE_STR, USSDCODE_TYPE_QUERY, USSDCODE_STAT_DUR, shmp->process_info.duration); #endif ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); shmp->process_info.sub_state = S_IDLE; retval = 1; // shmp->process_info.serviceKey = 1; // shmp->process_info.sub_state = S_MAP_WAIT_USSN_ACK; } break; case S_MAP_REST_TOPUP: retval = pps_rest_topup_process(portid); if(retval != 0) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_TOPUP_CODE_STR, USSDCODE_TYPE_TOPUP, USSDCODE_STAT_DUR, shmp->process_info.duration); #endif ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); shmp->process_info.sub_state = S_IDLE; retval = 1; // shmp->process_info.serviceKey = 2; // shmp->process_info.sub_state = S_MAP_WAIT_USSN_ACK; } break; case S_MAP_BUNDLE_PLAN: retval = pps_bundle_plan_process(portid); if(retval != 0) { ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); shmp->process_info.sub_state = S_IDLE; retval = 1; } break; case S_MAP_THIRD_PARTY_HOTLINE: retval = pps_third_party_plan_process(portid); if(retval != 0) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_DUR, shmp->process_info.duration); #endif ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); shmp->process_info.sub_state = S_IDLE; retval = 1; } break; case S_MAP_THIRD_PARTY_CHANNEL: retval = pps_third_party_channel_process(portid); if(retval != 0) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(shmp->process_info.ppsService.chnl_info.scUrl, USSDCODE_TYPE_CHANNEL, USSDCODE_STAT_DUR, shmp->process_info.duration); #endif ppsSendUSSDStatistics(shmp); pps_send_map_close(portid); shmp->process_info.sub_state = S_IDLE; retval = 1; } break; default: retval = 1; break; } return retval; } int pps_rest_test_process(int flag) { int portid; _state_data *shmp=(_state_data *) &smshm_ptr->state_data; portid = AssignProcID(0); if( portid< MAX_FSM_PROCESS && portid>=0 ) { shmp += portid; memset(shmp, 0x00, sizeof(_state_data)); DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d , %s , flag=%d\33[0m", portid, __FUNCTION__, flag); shmp->process_info.state = S_MAP_STATE; if(flag == 0) { shmp->process_info.sub_state = S_MAP_REST_QUERY; } else { shmp->process_info.sub_state = S_MAP_REST_TOPUP; strcpy((char *)shmp->called_info.number, "123456789012"); } strcpy((char *)shmp->caller_info.number, "86755900123"); } return 1; } int SmppRechargeProc(u_short portid) { _state_data *shmp; int retval=0; int error_code = ERR_REST_SUCCESS; PutLogFunID("SnmpRechargeProc"); shmp = (_state_data *)&smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) return -1; shmp += portid; if(shmp->process_info.funnel ++>SSHORT_DELAY_TIMER) { sendSMSRechargeNegativeResponse(shmp, OC_RESULT_SYSTEM_FAILURE); return -1; } switch(shmp->process_info.sub_state) { case 0: send_scf_update_card_data(portid); shmp->process_info.sub_state = 1; shmp->process_info.funnel = 0; shmp->process_info.update_card_ack = 0; break; case 1: if(!shmp->process_info.update_card_ack) { return retval; } if(shmp->process_info.update_card_result != OC_RESULT_OK) { RechargeFailedUpdateAccountData(portid); sendSMSRechargeNegativeResponse(shmp, shmp->process_info.update_card_result ); return (retval = -1); } RechargeRequestProc(portid); retval = 1; break; case 2: pps_send_selfcare_topup_req(portid); shmp->process_info.funnel = 0; shmp->process_info.rest_if.recv_cmd = 0; if(shmp->process_info.chargeFrom == 3) { shmp->process_info.sub_state = 4; } else shmp->process_info.sub_state = 3; break; case 3: if(shmp->process_info.rest_if.recv_cmd == 0) { return retval; } if(shmp->process_info.funnel>SSHORT_DELAY_TIMER) { return (retval = -1); } if(shmp->process_info.rest_if.result) { RechargeFailedUpdateAccountData(portid); sendSMSRechargeNegativeResponse(shmp, shmp->process_info.rest_if.result ); return (retval = -1); } RechargeSucceedwithCRM(portid); retval = 1; break; case 4: if(shmp->process_info.rest_if.recv_cmd == 0) { return retval; } if(shmp->process_info.funnel>SSHORT_DELAY_TIMER) { error_code = ERR_REST_UNABLE_TO_COMPLY; } if(shmp->process_info.rest_if.result) { switch(shmp->process_info.rest_if.result == 1) { case 1: error_code = ERR_REST_INVALID_RECHARGE_PWD; break; case 2: //error status error_code = ERR_REST_INVALID_PARAMETER_VALUE; break; case 3: //expired default: error_code = ERR_REST_INVALID_PARAMETER_VALUE; break; } } if(1) { int len; char msg_buf[256]; _rest_msg_s rest_rsp; _rest_recharge_card_rsp *pRsp = &rest_rsp.msg.recharge_card_rsp; memset(pRsp, 0, sizeof(_rest_recharge_card_rsp)); rest_rsp.msg_type = REST_RECHARGE_CARD_RSP; rest_rsp.header.dst_ref = shmp->process_info.rest_if.src_ref; rest_rsp.header.src_ref = shmp->process_info.rest_if.dst_ref; pRsp->error_code = error_code; if (error_code != ERR_REST_SUCCESS) { pRsp->result = RES_FAILED; pRsp->rechargeAmount = 0; } else { pRsp->result = RES_SUCCEED; RechargeSucceedwithCRM(portid); pRsp->rechargeAmount = shmp->process_info.rest_if.balance; } pRsp->balance = GetBalance(&shmp->caller_info); pRsp->expiredTime = (u64)GetExpiration(&shmp->caller_info); if((logMsgFlag & 0x04) || (logMsgFlag & 0x02) ) { DebugMsg(debugmib.display.asciiOut, "reply REST_RECHARGE_CARD_RSP, result[%d], recharge amount[%d], balance[%d]", \ error_code, pRsp->rechargeAmount, pRsp->balance); } len = encode_rest_recharge_card_rsp(&rest_rsp, (u8 *)msg_buf); pps_send_rest_msg((u8 *)msg_buf, len); } retval = 1; break; default: retval = 1; break; } return retval; } // for restproxy(zmobile) ========================================= char yx_ussd_menu[YX_USSD_MENU_NUM_MAX][512]= { /*0main*/"Welcome to the Ultimate DATA experience - zedmobile!\n1. UNLIMITED zedmobile calls and Data @ an Unbelievable K20 for 30 days\n2. zedDATA\n3. zedVOICE\n4. zedMIFI & Router\n5. Buy for Other\n6. Balance Check", /*1k20*/"Try our K20 UNLIMITED Calls & Data\n1. Yes\n0. To return to main menu", /*2data*/"1. 24 Hrs\n2. 7 days\n3. 30 days\n0. To return to main menu", /*3voice*/"1. Daily\n2. Weekly\n3. Monthly\n0. To return to main menu", /*4mifi*/"Welcome to the ULTIMATE DATA experience - zedmobile!\n1. K50 = 6 GB for 30 days\n2. K100 = 15GB for 30 days\n3. K200 = 40GB for 30 days\n4. K500 = 65GB +5GBDaily for 30 days + Unlimited netflix\n5. K700 = 80 GB + 6 GB daily for 30 days + Unlimited Netflix + Youtube\n6. K1000 = 100 GB +8Gb Daily + Unlimited netflix + Youtube\n0. To return to main menu", /*5buy4Other*/"Share the ULTIMATE DATA experience - zedmobile!\nKindly enter the number you wish to share a zedmobile bundle with.(098X xxxxxx)", /*6balanceCheck*/"Dear Customer, your balance is processed. You will receive a confirmation message shortly", /*7*/"", /*8*/"", /*9*/"", /*10data 24Hrs*/"1. K2= 100 MB for 24Hrs\n2. K5= 350 MB for 24Hrs\n3. K10= 1.5 GB for 24Hrs\n0. To return to main menu", /*11data 7days*/"1. K5= 500 MB for 7 days\n2. K10= 1 GB for 7 days\n3. K20= 2 GB for 7 days\n4. K50= 7.5 GB for 7 days\n0. To return to main menu", /*12data 30days*/"1. K50= 5 GB for 30 days\n2. K100= 10 GB for 30 days\n3. K200= 30 GB for 30 days\n0. To return to main menu", /*13voic Daily*/"Press\n1 . K2= 8 min allnet + 20MB + 50 SMS\n2. K5= 26 min allnet + 40MB + 100 SMS\n3. K10= 40 Min allnet + 70MB + 100 SMS\n0. To return to main menu", /*14voic Weekly*/"Press\n1. K5= 17 min allnet + 100MB + 50 SMS\n2. K10= 45 min allnet + 300 MB + 100 SMS\n3. K20= 120min allnet + 400MB +100 SMS\n4. K50= 350 min allnet + 500MB + 100 SMS\n0. To return to main menu", /*15voic Monthly*/"Press\n1. K50= 200 min allnet + 1 GB + 500 SMS\n2. K100= 725min allnet + 3GB + 500 SMS\n3. K200= 1750 min allnet + 5GB + 500 SMS\n4. K250= 800min allnet + 15GB + 500 SMS\n0. To return to main menu", /*16MIFI*/"", /*17otherMenu*/"1. ZedLife na K20\n2. zedDATA\n3. zedVoice\n4. zedMIFI & Router\n0. To return to main menu", /*18thirdParty*/"1. Airtel\n2. MTN", /*19enterPhone*/"Enter mobile number", /*20payMethod*/"1. Main account\n2. Mobile money", /*21Paid*/"Your transaction is being processed. You will receive a confirmation SMS soon. For the ULTIMATE experience use My zedLife App ( selfcare)\n1. Download zedLife App and don’t miss out on anything.\n0. To return to the main menu", /*22enterPin*/"Enter pin to confirm", /*23complete*/"Thank you. You will soon receive the link via text message.", /*24cancel auto renewal*/"Are you certain about canceling auto renewal?\n1. No\n2. Yes\n0. To return to main menu", }; char yx_chnl_info[YX_USSD_CHNL_NUM_MAX][128]= { }; char yx_momo_info[YX_MOBILE_MONEY_MAX][32]= {"Airtel Money", "MTN MoMo", "Zamtel Kwacha", ""}; int yx_offerIds[YX_OFFER_TYPE_MAX][YX_OFFER_PER_TYPE]; char yx_offerStrs[YX_OFFER_TYPE_MAX][YX_OFFER_PER_TYPE][128]= {}; int yx_ussd_daily_report = 0; extern int time_now[7]; int match_channel_info(char *sc, char *url) { int i; if (strlen(sc) < 3) { return 0; } for (i=0; i 12) && (strncmp(sc, yx_chnl_info[i], 3) == 0)) { strcpy(url, yx_chnl_info[i]); return 1; } } return 0; } int read_yx_ussd_param(void) { //char *temp_ptr; char info_str[512]; char sysconf[]="/usr/local/ussdgw/bin/conf/yx_ussd.conf"; FILE *fp = fopen(sysconf,"r");// read configure if (fp == NULL) { printf("can not open file %s!!\n",sysconf); return 0; } int i, ret; while (!feof(fp)) { info_str[0] = '\n'; ret = fgets(info_str, 250, fp); if (info_str[0] == '#' || info_str[0] == '\n') continue; i = 0; while (info_str[i] != '\0') { if (info_str[i] == '|') { info_str[i] = '\n'; } i++; } if(!strncasecmp(info_str,"dailyreport=", 12)) { yx_ussd_daily_report = atoi(&info_str[12]); } else if(!strncasecmp(info_str,"bundle11=", 9)) { yx_offerIds[YX_OFFER_TYPE_BUNDLE][0] = atoi(&info_str[9]); } else if(!strncasecmp(info_str,"bundle12=", 9)) { yx_offerIds[YX_OFFER_TYPE_BUNDLE][1] = atoi(&info_str[9]); } else if(!strncasecmp(info_str,"bundle13=", 9)) { yx_offerIds[YX_OFFER_TYPE_BUNDLE][2] = atoi(&info_str[9]); } else if(!strncasecmp(info_str,"bundle14=", 9)) { yx_offerIds[YX_OFFER_TYPE_BUNDLE][3] = atoi(&info_str[9]); } else if(!strncasecmp(info_str,"bundle15=", 9)) { yx_offerIds[YX_OFFER_TYPE_BUNDLE][4] = atoi(&info_str[9]); } else if(!strncasecmp(info_str,"bundle16=", 9)) { yx_offerIds[YX_OFFER_TYPE_BUNDLE][5] = atoi(&info_str[9]); } else if(!strncasecmp(info_str,"bundle17=", 9)) { yx_offerIds[YX_OFFER_TYPE_BUNDLE][6] = atoi(&info_str[9]); } else if(!strncasecmp(info_str,"bundle18=", 9)) { yx_offerIds[YX_OFFER_TYPE_BUNDLE][7] = atoi(&info_str[9]); } else if(!strncasecmp(info_str,"data11=", 7)) { yx_offerIds[YX_OFFER_TYPE_DATA_1][0] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"data12=", 7)) { yx_offerIds[YX_OFFER_TYPE_DATA_1][1] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"data13=", 7)) { yx_offerIds[YX_OFFER_TYPE_DATA_1][2] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"data14=", 7)) { yx_offerIds[YX_OFFER_TYPE_DATA_1][3] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"data21=", 7)) { yx_offerIds[YX_OFFER_TYPE_DATA_2][0] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"data22=", 7)) { yx_offerIds[YX_OFFER_TYPE_DATA_2][1] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"data23=", 7)) { yx_offerIds[YX_OFFER_TYPE_DATA_2][2] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"data24=", 7)) { yx_offerIds[YX_OFFER_TYPE_DATA_2][3] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"data31=", 7)) { yx_offerIds[YX_OFFER_TYPE_DATA_3][0] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"data32=", 7)) { yx_offerIds[YX_OFFER_TYPE_DATA_3][1] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"data33=", 7)) { yx_offerIds[YX_OFFER_TYPE_DATA_3][2] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"data34=", 7)) { yx_offerIds[YX_OFFER_TYPE_DATA_3][3] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"voice11=", 8)) { yx_offerIds[YX_OFFER_TYPE_VOICE_1][0] = atoi(&info_str[8]); } else if(!strncasecmp(info_str,"voice12=", 8)) { yx_offerIds[YX_OFFER_TYPE_VOICE_1][1] = atoi(&info_str[8]); } else if(!strncasecmp(info_str,"voice13=", 8)) { yx_offerIds[YX_OFFER_TYPE_VOICE_1][2] = atoi(&info_str[8]); } else if(!strncasecmp(info_str,"voice14=", 8)) { yx_offerIds[YX_OFFER_TYPE_VOICE_1][3] = atoi(&info_str[8]); } else if(!strncasecmp(info_str,"voice21=", 8)) { yx_offerIds[YX_OFFER_TYPE_VOICE_2][0] = atoi(&info_str[8]); } else if(!strncasecmp(info_str,"voice22=", 8)) { yx_offerIds[YX_OFFER_TYPE_VOICE_2][1] = atoi(&info_str[8]); } else if(!strncasecmp(info_str,"voice23=", 8)) { yx_offerIds[YX_OFFER_TYPE_VOICE_2][2] = atoi(&info_str[8]); } else if(!strncasecmp(info_str,"voice24=", 8)) { yx_offerIds[YX_OFFER_TYPE_VOICE_2][3] = atoi(&info_str[8]); } else if(!strncasecmp(info_str,"voice31=", 8)) { yx_offerIds[YX_OFFER_TYPE_VOICE_3][0] = atoi(&info_str[8]); } else if(!strncasecmp(info_str,"voice32=", 8)) { yx_offerIds[YX_OFFER_TYPE_VOICE_3][1] = atoi(&info_str[8]); } else if(!strncasecmp(info_str,"voice33=", 8)) { yx_offerIds[YX_OFFER_TYPE_VOICE_3][2] = atoi(&info_str[8]); } else if(!strncasecmp(info_str,"voice34=", 8)) { yx_offerIds[YX_OFFER_TYPE_VOICE_3][3] = atoi(&info_str[8]); } else if(!strncasecmp(info_str,"mifi11=", 7)) { yx_offerIds[YX_OFFER_TYPE_MIFI_1][0] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"mifi12=", 7)) { yx_offerIds[YX_OFFER_TYPE_MIFI_1][1] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"mifi13=", 7)) { yx_offerIds[YX_OFFER_TYPE_MIFI_1][2] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"mifi14=", 7)) { yx_offerIds[YX_OFFER_TYPE_MIFI_1][3] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"mifi15=", 7)) { yx_offerIds[YX_OFFER_TYPE_MIFI_1][4] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"mifi16=", 7)) { yx_offerIds[YX_OFFER_TYPE_MIFI_1][5] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"mifi17=", 7)) { yx_offerIds[YX_OFFER_TYPE_MIFI_1][6] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"ama01=", 6)) { yx_offerIds[YX_OFFER_TYPE_AMA_1][0] = atoi(&info_str[6]); } else if(!strncasecmp(info_str,"ama02=", 6)) { yx_offerIds[YX_OFFER_TYPE_AMA_1][1] = atoi(&info_str[6]); } else if(!strncasecmp(info_str,"ama03=", 6)) { yx_offerIds[YX_OFFER_TYPE_AMA_1][2] = atoi(&info_str[6]); } else if(!strncasecmp(info_str,"ama04=", 6)) { yx_offerIds[YX_OFFER_TYPE_AMA_1][3] = atoi(&info_str[6]); } else if(!strncasecmp(info_str,"ama05=", 6)) { yx_offerIds[YX_OFFER_TYPE_AMA_1][4] = atoi(&info_str[6]); } else if(!strncasecmp(info_str,"ama06=", 6)) { yx_offerIds[YX_OFFER_TYPE_AMA_1][5] = atoi(&info_str[6]); } else if(!strncasecmp(info_str,"ama07=", 6)) { yx_offerIds[YX_OFFER_TYPE_AMA_1][6] = atoi(&info_str[6]); } else if(!strncasecmp(info_str,"diba01=", 7)) { yx_offerIds[YX_OFFER_TYPE_DIBA_1][0] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"diba02=", 7)) { yx_offerIds[YX_OFFER_TYPE_DIBA_1][1] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"diba03=", 7)) { yx_offerIds[YX_OFFER_TYPE_DIBA_1][2] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"diba04=", 7)) { yx_offerIds[YX_OFFER_TYPE_DIBA_1][3] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"diba05=", 7)) { yx_offerIds[YX_OFFER_TYPE_DIBA_1][4] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"diba06=", 7)) { yx_offerIds[YX_OFFER_TYPE_DIBA_1][5] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"diba07=", 7)) { yx_offerIds[YX_OFFER_TYPE_DIBA_1][6] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"diba08=", 7)) { yx_offerIds[YX_OFFER_TYPE_DIBA_1][7] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"diba09=", 7)) { yx_offerIds[YX_OFFER_TYPE_DIBA_1][8] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"diba10=", 7)) { yx_offerIds[YX_OFFER_TYPE_DIBA_1][9] = atoi(&info_str[7]); } else if(!strncasecmp(info_str,"diba01str=", 10)) { snprintf(yx_offerStrs[YX_OFFER_TYPE_DIBA_1][0], 127, "%s", &info_str[10]);//strncpy(yx_offerStrs[YX_OFFER_TYPE_DIBA_1][0], &info_str[10], 127); } else if(!strncasecmp(info_str,"diba02str=", 10)) { snprintf(yx_offerStrs[YX_OFFER_TYPE_DIBA_1][1], 127, "%s", &info_str[10]); } else if(!strncasecmp(info_str,"diba03str=", 10)) { snprintf(yx_offerStrs[YX_OFFER_TYPE_DIBA_1][2], 127, "%s", &info_str[10]); } else if(!strncasecmp(info_str,"diba04str=", 10)) { snprintf(yx_offerStrs[YX_OFFER_TYPE_DIBA_1][3], 127, "%s", &info_str[10]); } else if(!strncasecmp(info_str,"diba05str=", 10)) { snprintf(yx_offerStrs[YX_OFFER_TYPE_DIBA_1][4], 127, "%s", &info_str[10]); } else if(!strncasecmp(info_str,"0main=",6)) { strcpy(yx_ussd_menu[0], &info_str[6]); } else if(!strncasecmp(info_str,"1k20=",5)) { strcpy(yx_ussd_menu[1], &info_str[5]); } else if(!strncasecmp(info_str,"2data=",6)) { strcpy(yx_ussd_menu[2], &info_str[6]); } else if(!strncasecmp(info_str,"3voice=",7)) { strcpy(yx_ussd_menu[3], &info_str[7]); } else if(!strncasecmp(info_str,"4mifi=",6)) { strcpy(yx_ussd_menu[4], &info_str[6]); } else if(!strncasecmp(info_str,"5buy4Other=",11)) { strcpy(yx_ussd_menu[5], &info_str[11]); } else if(!strncasecmp(info_str,"6balanceCheck=",14)) { strcpy(yx_ussd_menu[6], &info_str[14]); } else if(!strncasecmp(info_str,"7ama=",5)) { strcpy(yx_ussd_menu[YX_USSD_MENU_PRESS_AMA], &info_str[5]); } else if(!strncasecmp(info_str,"8unlimited=",11)) { strcpy(yx_ussd_menu[YX_USSD_MENU_PRESS_UNLIMITED_BUNDLES], &info_str[11]); } else if(!strncasecmp(info_str,"9airtime=",9)) { strcpy(yx_ussd_menu[YX_USSD_MENU_PRESS_PURCHASE_AIRTIME], &info_str[9]); } else if(!strncasecmp(info_str,"10data24Hrs=",12)) { strcpy(yx_ussd_menu[10], &info_str[12]); } else if(!strncasecmp(info_str,"11data7days=",12)) { strcpy(yx_ussd_menu[11], &info_str[12]); } else if(!strncasecmp(info_str,"12data30days=",13)) { strcpy(yx_ussd_menu[12], &info_str[13]); } else if(!strncasecmp(info_str,"13voiceDaily=",13)) { strcpy(yx_ussd_menu[13], &info_str[13]); } else if(!strncasecmp(info_str,"14voiceWeekly=",14)) { strcpy(yx_ussd_menu[14], &info_str[14]); } else if(!strncasecmp(info_str,"15voiceMonthly=",15)) { strcpy(yx_ussd_menu[15], &info_str[15]); } else if(!strncasecmp(info_str,"17otherMenu=",12)) { strcpy(yx_ussd_menu[17], &info_str[12]); } else if(!strncasecmp(info_str,"18thirdParty=",13)) { strcpy(yx_ussd_menu[18], &info_str[13]); /* mobile moneys int i=0, offset; char *token; char delimiter[] = "|"; char str[160]=""; strncpy(str, yx_ussd_menu[18], 159); token = strtok(str, delimiter); while ((token != NULL) && (i < YX_MOBILE_MONEY_MAX)) { if (token[0]<'0' || token[0]>'9') { token = strtok(NULL, delimiter); continue; } offset = 2; if (token[2] == ' ') { offset = 3; } strncpy(yx_momo_info[i], &token[offset], 31); i++; token = strtok(NULL, delimiter); }*/ } else if(!strncasecmp(info_str,"19enterPhone=",13)) { strcpy(yx_ussd_menu[19], &info_str[13]); } else if(!strncasecmp(info_str,"20payMethod=",12)) { strcpy(yx_ussd_menu[20], &info_str[12]); } else if(!strncasecmp(info_str,"21Paid=",7)) { strcpy(yx_ussd_menu[21], &info_str[7]); } else if(!strncasecmp(info_str,"22enterPin=",11)) { strcpy(yx_ussd_menu[22], &info_str[11]); } else if(!strncasecmp(info_str,"23complete=",11)) { strcpy(yx_ussd_menu[23], &info_str[11]); } else if(!strncasecmp(info_str,"24cancelrenewal=",16)) { strcpy(yx_ussd_menu[24], &info_str[16]); } else if(!strncasecmp(info_str,"25enteramount=",14)) { strcpy(yx_ussd_menu[YX_USSD_MENU_AIRTIME_AMOUNT], &info_str[14]); } else if(!strncasecmp(info_str,"26airtimeno=",12)) { strcpy(yx_ussd_menu[YX_USSD_MENU_AIRTIME_NO], &info_str[12]); } else if(!strncasecmp(info_str,"27dibaama=",10)) { strcpy(yx_ussd_menu[YX_USSD_MENU_DIBAAMA], &info_str[10]); } else if(!strncasecmp(info_str,"28diba=",7)) { strcpy(yx_ussd_menu[YX_USSD_MENU_DIBA], &info_str[7]); } else if(!strncasecmp(info_str,"29momopin=",10)) { strcpy(yx_ussd_menu[YX_USSD_MENU_MOMO_PIN], &info_str[10]); } else if(!strncasecmp(info_str,"30promo=",8)) { strcpy(yx_ussd_menu[YX_USSD_MENU_PROMO], &info_str[8]); } else if(!strncasecmp(info_str,"31querypoint=",13)) { strcpy(yx_ussd_menu[YX_USSD_MENU_QUERY_POINT], &info_str[13]); } else if(!strncasecmp(info_str,"32curpoint=",11)) { strcpy(yx_ussd_menu[YX_USSD_MENU_CUR_POINT], &info_str[11]); } else if(!strncasecmp(info_str,"33point2num=",12)) { strcpy(yx_ussd_menu[YX_USSD_MENU_POINT2NUM], &info_str[12]); } else if(!strncasecmp(info_str,"34offerchange=",14)) { strcpy(yx_ussd_menu[YX_USSD_MENU_OFFER_CHANGED], &info_str[14]); } else if(!strncasecmp(info_str,"35pointtrans=",13)) { strcpy(yx_ussd_menu[YX_USSD_MENU_POINT_TRANSFERED], &info_str[13]); } else if(!strncasecmp(info_str,"36pointlow=",11)) { strcpy(yx_ussd_menu[YX_USSD_MENU_POINT_LOW], &info_str[11]); } else if(!strncasecmp(info_str,"37offerout=",11)) { strcpy(yx_ussd_menu[YX_USSD_MENU_OFFER_OUT], &info_str[11]); } else if(!strncasecmp(info_str,"38transfail=",12)) { strcpy(yx_ussd_menu[YX_USSD_MENU_POINT_TRANS_FAIL], &info_str[12]); } else if(!strncasecmp(info_str,"39shareno=",10)) { strcpy(yx_ussd_menu[YX_USSD_MENU_SHARE_NBR], &info_str[10]); } else if(!strncasecmp(info_str,"channel00=", 10)) { strcpy(yx_chnl_info[0], &info_str[10]); } else if(!strncasecmp(info_str,"channel01=", 10)) { strcpy(yx_chnl_info[1], &info_str[10]); } else if(!strncasecmp(info_str,"channel02=", 10)) { strcpy(yx_chnl_info[2], &info_str[10]); } else if(!strncasecmp(info_str,"channel03=", 10)) { strcpy(yx_chnl_info[3], &info_str[10]); } else if(!strncasecmp(info_str,"channel04=", 10)) { strcpy(yx_chnl_info[4], &info_str[10]); } else if(!strncasecmp(info_str,"channel05=", 10)) { strcpy(yx_chnl_info[5], &info_str[10]); } else if(!strncasecmp(info_str,"channel06=", 10)) { strcpy(yx_chnl_info[6], &info_str[10]); } else if(!strncasecmp(info_str,"channel07=", 10)) { strcpy(yx_chnl_info[7], &info_str[10]); } else if(!strncasecmp(info_str,"channel08=", 10)) { strcpy(yx_chnl_info[8], &info_str[10]); } else if(!strncasecmp(info_str,"channel09=", 10)) { strcpy(yx_chnl_info[9], &info_str[10]); } else if(!strncasecmp(info_str,"channel10=", 10)) { strcpy(yx_chnl_info[10], &info_str[10]); } else if(!strncasecmp(info_str,"channel11=", 10)) { strcpy(yx_chnl_info[11], &info_str[10]); } else if(!strncasecmp(info_str,"channel12=", 10)) { strcpy(yx_chnl_info[12], &info_str[10]); } else if(!strncasecmp(info_str,"channel13=", 10)) { strcpy(yx_chnl_info[13], &info_str[10]); } else if(!strncasecmp(info_str,"channel14=", 10)) { strcpy(yx_chnl_info[14], &info_str[10]); } else if(!strncasecmp(info_str,"channel15=", 10)) { strcpy(yx_chnl_info[15], &info_str[10]); } } fclose(fp); return 1; } int pps_third_party_plan_process(u_short portid) { char ussd_data[1024]; int retval = 0, result=0; int key_input; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); if(shmp->process_info.funnel ++ > 100*CYCLE_STATE_INTERVAL) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_TIMEOUT, 0); #endif return -1; } switch(shmp->process_info.sub_state_2 ) { case 1: if(shmp->process_info.serviceInput++ > 3) { SendPSSRResponse(portid); return 1; } shmp->process_info.funnel = 0; shmp->process_info.rest_if.plan_id = 0; shmp->process_info.rest_if.bundle_plan_id = 0; shmp->process_info.routing_number[0] = '\0'; SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_MAIN]); shmp->process_info.sub_state_2 = 2; break; case 2: result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_UNLIMITED_BUNDLES]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 20;//1. UNLIMITED Data break; case 2: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_ZED_DATA]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 22;//zedDATA break; case 3: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_ZED_VOICE]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 23;//zedVOICE break; case 4: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_MIFI_AND_ROUTER]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 24;//zedMifi & Router break; case 5: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_INPUT_NO]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 25;//Buy for Other break; case 6: //SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_BALANCE_CHECK]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 26;//Balance Check, inform BOSS break; case 7: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_PURCHASE_AIRTIME]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 28;//Recharge Airtime break; case 8:// KaBoosta: redirect to 118 if (match_channel_info("118", shmp->process_info.ppsService.chnl_info.scUrl) > 0) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state("118", USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_REQ, 0); #endif shmp->process_info.sub_state = S_MAP_THIRD_PARTY_CHANNEL; shmp->process_info.sub_state_2 = 1; break; } break; case 0: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_DIBAAMA]);// YX_USSD_MENU_PRESS_AMA shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 15;//27;//diba & amaFive break; default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break;// case 3: if(shmp->process_info.serviceInput++ > 3) { SendPSSRResponse(portid); return 1; } SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_BUY_FOR_OTHER]);// menu 1-4 shmp->process_info.sub_state_2 = 4; break; case 4:// Buy for others, select menu 1-4 result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { shmp->process_info.sub_state_2 = 3; shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { shmp->process_info.sub_state_2 = 3; shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_UNLIMITED_BUNDLES]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 20;//1. UNLIMITED Data break; case 2: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_ZED_DATA]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 22;//zedDATA break; case 3: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_ZED_VOICE]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 23;//zedVOICE break; case 4: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_MIFI_AND_ROUTER]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 24;//zedMifi & Router break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 10:// Recharge Promo result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1:// Opt-in, send transfer Plan and return pps_send_rest_offer_change_req(portid, 0); SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_OFFER_CHANGED]); shmp->process_info.serviceInput = 0; retval = 1; break; case 2:// Query Bonus, send query points pps_send_rest_point_query_req(portid); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 11;// query points break; case 3:// Transfer Gift //pps_send_rest_point_query_req(portid); SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_CUR_POINT]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 13;// transfer Gift break; case 4:// Opt-out, send transfer Plan and return pps_send_rest_offer_change_req(portid, 1); SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_OFFER_OUT]); shmp->process_info.serviceInput = 0; retval = 1; break; default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break;// case 11:// query points if(shmp->process_info.rest_if.recv_cmd == 0) break; shmp->process_info.rest_if.recv_cmd = 0; result = shmp->process_info.rest_if.result; if(result == 0) { retval = 1; sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_QUERY_POINT], shmp->process_info.rest_if.unit, shmp->process_info.rest_if.balance/100, shmp->process_info.rest_if.balance%100); } else { retval = -1; sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_QUERY_POINT], 0); } if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d , recv query_points_res, result=%d, point=%d\33[0m", portid, result, shmp->process_info.rest_if.unit); } SendPSSREnd(portid, ussd_data); break; case 12:// current points if(shmp->process_info.rest_if.recv_cmd == 0) break; shmp->process_info.rest_if.recv_cmd = 0; result = shmp->process_info.rest_if.result; if(result == 0) { /*if (shmp->process_info.rest_if.unit <= 0) { retval = -1; sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_QUERY_POINT], 0); SendPSSREnd(portid, ussd_data); } else { sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_CUR_POINT], shmp->process_info.rest_if.unit); SendUSSDRequest(portid, ussd_data); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 13;// enter number that transfer Gift to }*/ sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_POINT_TRANSFERED], shmp->process_info.rest_if.unit, shmp->process_info.routing_number); SendPSSREnd(portid, ussd_data); retval = 1; } else { retval = -1; sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_POINT_TRANS_FAIL], shmp->process_info.routing_number); SendPSSREnd(portid, ussd_data); } if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d , recv query_points_res, result=%d, point=%d\33[0m", portid, result, shmp->process_info.rest_if.unit); } break; case 13:// input No. transfer Gift for result = getUssdACK(portid, (u_char *)shmp->process_info.routing_number); if(result >= 1) { sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_POINT2NUM], shmp->process_info.routing_number); SendUSSDRequest(portid, ussd_data); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 14;// =>Amount Input shmp->process_info.funnel = 0; } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 14:// Point Amount Input result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { break; } else { key_input = atoi(shmp->process_info.tmpDigits); if (key_input <= 0) { SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_POINT_LOW]); retval = 1; } else { shmp->process_info.rest_if.unit = key_input; pps_send_rest_point_transfer_req(portid, 1070); //sprintf(ussd_data, yx_ussd_menu[YX_USSD_MENU_POINT_TRANSFERED], shmp->process_info.rest_if.unit, shmp->process_info.routing_number); //SendPSSREnd(portid, ussd_data); } //retval = 1; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 12;// =>wait result } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 15: result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 2: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_DIBA]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 16;//diba 5x break; case 1: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PROMO]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 10;//Recharge Promo break; case 3: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_AMA]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 27;//amaFive break; case 4:// 4. K1 - Weekend 150MB offerId: 267067 SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_AMA_1][6]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break;// case 16:// 0, DIBA sub menu result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1: case 2: case 3: case 4: case 5: { char tmp_buf[160]=""; snprintf(tmp_buf, 159, "%s\n%s", yx_offerStrs[YX_OFFER_TYPE_DIBA_1][key_input-1], yx_ussd_menu[YX_USSD_MENU_UNLIMITED_ONCE_RECUR]); SendUSSDRequest(portid, tmp_buf);//yx_ussd_menu[YX_USSD_MENU_UNLIMITED_ONCE_RECUR]); } shmp->process_info.rest_if.bundle_plan_id = key_input -1; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 17;//once, recur or cancel shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 17:// 0, diba: once, recur result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { int bundleId = shmp->process_info.rest_if.bundle_plan_id * 2; key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1:// once off SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_DIBA_1][bundleId]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; case 2:// recur SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_DIBA_1][bundleId + 1]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; case 3:// cancel recur SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_CANCEL_RENEWAL]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_DIBA_1][bundleId + 1]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 36;//cancel auto renewal shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 18:// input No. share airtime with result = getUssdACK(portid, (u_char *)shmp->process_info.routing_number); if(result >= 1) { SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_AIRTIME_AMOUNT]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 19;// =>Airtime Amount Input shmp->process_info.funnel = 0; } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 19:// Airtime Amount Input, share with result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { break; } else { key_input = atoi(shmp->process_info.tmpDigits); shmp->process_info.rest_if.unit = key_input; pps_send_rest_point_transfer_req(portid, 1069); SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_PAID_MONEY]); retval = 1; } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 20:// unlimited data result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1:// K20 Unlimited-24hrs /*SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_UNLIMITED_ONCE_RECUR]); shmp->process_info.rest_if.bundle_plan_id = 0;// yx_offerIds[YX_OFFER_TYPE_BUNDLE][0]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 21;//once, recur or cancel shmp->process_info.funnel = 0;*/ SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_BUNDLE][0]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; case 2:// K20 Unlimited-3 Days SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_UNLIMITED_ONCE_RECUR]); shmp->process_info.rest_if.bundle_plan_id = 1;// yx_offerIds[YX_OFFER_TYPE_BUNDLE][2]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 21;//once, recur or cancel shmp->process_info.funnel = 0; break; case 3:// K100 Unlimited-7 Days SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_UNLIMITED_ONCE_RECUR]); shmp->process_info.rest_if.bundle_plan_id = 2;//yx_offerIds[YX_OFFER_TYPE_BUNDLE][3]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 21;//once, recur or cancel shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 21:// 1, k20 unlimited calls and data result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { int bundleId = shmp->process_info.rest_if.bundle_plan_id * 2; key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_BUNDLE][bundleId]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; case 2: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_BUNDLE][bundleId + 1]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; case 3: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_CANCEL_RENEWAL]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_BUNDLE][bundleId + 1]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 36;//cancel auto renewal shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 22:// 2, zed DATA result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1:// 24Hrs SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_DATA_24HRS]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 41; shmp->process_info.funnel = 0; break; case 2:// 7 days SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_DATA_7DAYS]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 42; shmp->process_info.funnel = 0; break; case 3:// 30 days SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_DATA_30DAYS]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 43; shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 23:// 3, zed VOICE result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1:// 24Hrs SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_VOICE_DAILY]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 51; shmp->process_info.funnel = 0; break; case 2:// 7 days SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_VOICE_WEEKLY]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 52; shmp->process_info.funnel = 0; break; case 3:// 30 days SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_VOICE_MONTHLY]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 53; shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 24:// 4, MIFI sub menu result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1: case 2: case 3: case 4: case 5: case 6: case 7: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_MIFI_1][key_input-1]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 25:// input No. result = getUssdACK(portid, (u_char *)shmp->process_info.routing_number); if(result >= 1) { //SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_BUY_FOR_OTHER]);// menu 1-4 shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 3; shmp->process_info.funnel = 0; } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 26:// Balance Check if (1) { pps_send_rest_free_resource_req(portid);// send free resource req, no need to handle rsp } SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_PRESS_BALANCE_CHECK]); retval = 1; break; case 27:// 0, AMA sub menu result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1: case 2: case 3: case 4: case 5: case 6: //case 7: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_AMA_1][key_input-1]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 28:// 7. Recharge Airtime result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1:// Buy for self, order->msisdn = shmp->caller_info.number SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_AIRTIME_AMOUNT]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 30;//=>Airtime Amount Input shmp->process_info.funnel = 0; break; case 2:// Buy for other SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_AIRTIME_NO]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 29;//=>input No. buy airtime for shmp->process_info.funnel = 0; break; case 3:// Me2U SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SHARE_NBR]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 18;//=>input No. share airtime with shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 29:// input No. buy airtime for result = getUssdACK(portid, (u_char *)shmp->process_info.routing_number); if(result >= 1) { SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_AIRTIME_AMOUNT]); shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 30;// =>Airtime Amount Input shmp->process_info.funnel = 0; } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 30:// Airtime Amount Input result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { break; } else { key_input = atoi(shmp->process_info.tmpDigits); shmp->process_info.rest_if.balance = (long)key_input; SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_PROVIDER]); shmp->process_info.rest_if.plan_id = 10;// mobile money shmp->process_info.rest_if.busicode = 1000;// busicode: recharge shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 34;//select provider; 33;//enter pin shmp->process_info.funnel = 0; } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 41:// zed Data sub 24Hrs result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1: case 2: case 3: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_DATA_1][key_input-1]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 42:// zed Data sub 7 days result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1: case 2: case 3: case 4: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_DATA_2][key_input-1]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 43:// zed Data sub 30 days result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1: case 2: case 3: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_DATA_3][key_input-1]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 51:// zed VOICE sub daily result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1: case 2: case 3: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_VOICE_1][key_input-1]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 52:// zed VOICE sub weekly result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1: case 2: case 3: case 4: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_VOICE_2][key_input-1]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 53:// zed VOICE sub monthly result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1: case 2: case 3: case 4: SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_MONEY]); shmp->process_info.rest_if.bundle_plan_id = yx_offerIds[YX_OFFER_TYPE_VOICE_3][key_input-1]; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 31;//select money shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 31:// select money result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1:// pay by balance shmp->process_info.rest_if.plan_id = 4;// balance if (1)//(pps_get_adaptor_flag()) { pps_send_rest_order_req(portid, 1001);// send bundle subs req /*shmp->process_info.funnel = 0; shmp->process_info.rest_if.timer = 0; shmp->process_info.rest_if.recv_cmd = 0; shmp->process_info.sub_state_2 = 11;*/ } SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_PAID_MONEY]);// SendUSSDRequest shmp->process_info.serviceInput = 0; //shmp->process_info.sub_state_2 = 32;//paid money retval = 1; break; case 2:// pay by mobile money SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_SELECT_PROVIDER]); shmp->process_info.rest_if.plan_id = 10;// mobile money shmp->process_info.rest_if.busicode = 1001;// busicode: order shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 34;//select provider; 33;//enter pin shmp->process_info.funnel = 0; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 32:// paid result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1:// complete // send download app req pps_send_rest_download_app_req(portid); SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_SUBSCRIB_COMPLETE]); retval = 1; break; case 0: default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 33:// enter pin, not in used currently result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { // subscribe bundle if (1)//(pps_get_adaptor_flag()) { pps_send_rest_order_req(portid, 1001);// send bundle subs req /*shmp->process_info.funnel = 0; shmp->process_info.rest_if.timer = 0; shmp->process_info.rest_if.recv_cmd = 0; shmp->process_info.sub_state_2 = 11;*/ } SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_PAID_MONEY]);//SendUSSDRequest shmp->process_info.serviceInput = 0; //shmp->process_info.sub_state_2 = 32;//paid money retval = 1; } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 34:// select provider result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 1:// Airtel case 2:// MTN case 3:// Zemtel case 4:// NULL case 5:// NULL shmp->process_info.rest_if.unit = key_input;// operator if (strstr(yx_ussd_menu[YX_USSD_MENU_ENTER_PAY_NUMBER], "%s") != NULL) { char tmp_buf[160]=""; sprintf(tmp_buf, (char *)yx_ussd_menu[YX_USSD_MENU_ENTER_PAY_NUMBER], (char *)yx_momo_info[key_input-1]); SendUSSDRequest(portid, tmp_buf); } else { SendUSSDRequest(portid, yx_ussd_menu[YX_USSD_MENU_ENTER_PAY_NUMBER]); } shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 35;//enter pay number break; case 0: default: //shmp->process_info.serviceInput = 0; //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 35:// enter pay number result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { // subscribe bundle if (1)//(pps_get_adaptor_flag()) { pps_send_rest_order_req(portid, shmp->process_info.rest_if.busicode);// send bundle subs req } if (strstr(yx_ussd_menu[YX_USSD_MENU_MOMO_PIN], "%s") != NULL) { char tmp_buf[160]="", tmp_nbr[64]=""; sprintf(tmp_nbr, "%s %s", yx_momo_info[shmp->process_info.rest_if.unit-1], shmp->process_info.tmpDigits); sprintf(tmp_buf, (char *)yx_ussd_menu[YX_USSD_MENU_MOMO_PIN], tmp_nbr); SendPSSREnd(portid, tmp_buf);//SendUSSDRequest } else { SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_MOMO_PIN]);//SendUSSDRequest } shmp->process_info.serviceInput = 0; //shmp->process_info.sub_state_2 = 32;//paid money retval = 1; } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; case 36:// cancel auto renewal result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { if(strlen(shmp->process_info.tmpDigits) > 1) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } if(isdigit(shmp->process_info.tmpDigits[0]) == 0) { //shmp->process_info.sub_state_2 = 1; //shmp->process_info.funnel = 0; break; } else { key_input = atoi(shmp->process_info.tmpDigits); switch(key_input) { case 2:// Yes // send cancel auto renewal req shmp->process_info.rest_if.plan_id = 4;// balance pps_send_rest_order_req(portid, 1002); SendPSSREnd(portid, yx_ussd_menu[YX_USSD_MENU_PAID_MONEY]);//SendUSSDRequest shmp->process_info.serviceInput = 0; //shmp->process_info.sub_state_2 = 32;//paid money retval = 1; break; case 0: case 1:// No default: shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 1; shmp->process_info.funnel = 0; break; } } } else if(result == -1) { #ifdef _ZED_NO_CALLER_NUM_AND_EXPIRY_DATE_ // ussd_code daily report pps_update_ussd_code_state(USSDCODE_HOTLINE_CODE_STR, USSDCODE_TYPE_HOTLINE, USSDCODE_STAT_ERR_MSG, 0); #endif SendPSSRResponse(portid); retval = 1; } break; } return retval; } int pps_third_party_channel_process(u_short portid) { int retval = 0, result; int key_input; char ussd_data[256]; _state_data *shmp = (_state_data *) smshm_ptr->state_data; if(portid>=MAX_FSM_PROCESS) { return -1; } shmp += (portid); if(shmp->process_info.rest_if.timer ++ > 100*CYCLE_STATE_INTERVAL) { return -1; } switch(shmp->process_info.sub_state_2) { case 1: shmp->process_info.ppsService.chnl_info.input[0] = '\0'; shmp->process_info.ppsService.chnl_info.prompt[0] = '\0'; sprintf(shmp->process_info.ppsService.chnl_info.sessId,"%04d%02d%02d%02d%02d%02d%s", time_now[0],time_now[1],time_now[2], time_now[3],time_now[4],time_now[5], shmp->caller_info.number); pps_send_rest_channel_req(portid);// send channel req shmp->process_info.rest_if.timer = 0; shmp->process_info.rest_if.recv_cmd = 0; shmp->process_info.sub_state_2 = 2; break; case 2: if(shmp->process_info.rest_if.recv_cmd == 0) break; result = shmp->process_info.rest_if.result; if((logMsgFlag & 0x01) || shmp->process_info.logMsisdn) { DebugMsg(debugmib.display.asciiOut, "\n\33[31m portid: %d, recv channel_res, result=%d\33[0m", portid, result); } if(result != 0)// error { SendPSSRResponse(portid); retval = 1; } else { if (shmp->process_info.ppsService.chnl_info.sess_state == 1)// continue { sprintf(ussd_data, "%s", shmp->process_info.ppsService.chnl_info.prompt); SendUSSDRequest(portid, ussd_data); shmp->process_info.funnel = 0; shmp->process_info.rest_if.timer = 0; shmp->process_info.serviceInput = 0; shmp->process_info.sub_state_2 = 3; } else// 0, terminate { sprintf(ussd_data, "%s", shmp->process_info.ppsService.chnl_info.prompt); SendPSSREnd(portid, ussd_data); retval = 1; } } break; case 3: result = getUssdACK(portid, (u_char *)shmp->process_info.tmpDigits); if(result >= 1) { strncpy(shmp->process_info.ppsService.chnl_info.input, shmp->process_info.tmpDigits, MAX_ASCII_NUMBER_LEN-1); pps_send_rest_channel_req(portid);// send channel req shmp->process_info.funnel = 0; shmp->process_info.rest_if.timer = 0; shmp->process_info.rest_if.recv_cmd = 0; shmp->process_info.sub_state_2 = 2; } else if(result == -1) { SendPSSRResponse(portid); retval = 1; } break; default: retval = -1; break; } return retval; } //