Search in sources :

Example 1 with MultipleServicesCreditControlAvp

use of net.java.slee.resource.diameter.cca.events.avp.MultipleServicesCreditControlAvp in project charging-server by RestComm.

the class DiameterChargingServerSbb method createCCA.

/**
 * @param ccServerActivity
 * @param request
 * @param reservations
 * @param resultCode
 * @return
 */
private RoCreditControlAnswer createCCA(RoServerSessionActivity ccServerActivity, RoCreditControlRequest request, List<CreditControlInfo> reservations, long resultCode) {
    RoCreditControlAnswer answer = ccServerActivity.createRoCreditControlAnswer();
    // <Credit-Control-Answer> ::= < Diameter Header: 272, PXY >
    // < Session-Id >
    // { Result-Code }
    answer.setResultCode(resultCode);
    // *[ AVP ]
    if (reservations != null && reservations.size() > 0) {
        MultipleServicesCreditControlAvp[] reqMSCCs = request.getMultipleServicesCreditControls();
        List<MultipleServicesCreditControlAvp> ansMSCCs = new ArrayList<MultipleServicesCreditControlAvp>();
        for (int index = 0; index < reqMSCCs.length; index++) {
            MultipleServicesCreditControlAvp reqMSCC = reqMSCCs[index];
            MultipleServicesCreditControlAvp ansMscc = avpFactory.createMultipleServicesCreditControl();
            ansMscc.setRatingGroup(reqMSCC.getRatingGroup());
            ansMscc.setServiceIdentifiers(reqMSCC.getServiceIdentifiers());
            // FIXME: Check how to handle this in case of MSCC if anything different is needed
            CreditControlInfo ccInfo = reservations.get(reservations.size() - 1);
            if (ccInfo.isSuccessful()) {
                GrantedServiceUnitAvp gsu = avpFactory.createGrantedServiceUnit();
                ArrayList<CreditControlUnit> ccUnits = ccInfo.getCcUnits();
                for (int i = 0; i < ccUnits.size(); i++) {
                    CreditControlUnit ccUnit = ccUnits.get(i);
                    if (ccUnit.getUnitType() == CcUnitType.INPUT_OCTETS) {
                        gsu.setCreditControlInputOctets(ccUnit.getReservedUnits());
                    }
                    // TODO: Add CC-Money support if not 3GPP ?
                    if (ccUnit.getUnitType() == CcUnitType.OUTPUT_OCTETS) {
                        gsu.setCreditControlOutputOctets(ccUnit.getReservedUnits());
                    }
                    if (ccUnit.getUnitType() == CcUnitType.SERVICE_SPECIFIC_UNITS) {
                        gsu.setCreditControlServiceSpecificUnits(ccUnit.getReservedUnits());
                    }
                    if (ccUnit.getUnitType() == CcUnitType.TIME) {
                        gsu.setCreditControlTime(ccUnit.getReservedUnits());
                    }
                    if (ccUnit.getUnitType() == CcUnitType.TOTAL_OCTETS) {
                        gsu.setCreditControlTotalOctets(ccUnit.getReservedUnits());
                    }
                }
                ansMscc.setGrantedServiceUnit(gsu);
                ansMscc.setResultCode(DiameterResultCode.DIAMETER_SUCCESS);
                // If we are terminating gracefully we MAY include the Final-Unit-Indication
                if (answer.getCcRequestType() == CcRequestType.TERMINATION_REQUEST) {
                    FinalUnitIndicationAvp fuiAvp = avpFactory.createFinalUnitIndication();
                    fuiAvp.setFinalUnitAction(FinalUnitActionType.TERMINATE);
                    ansMscc.setFinalUnitIndication(fuiAvp);
                }
            } else {
                // In case it's not successful we want to have Final-Unit-Indication
                FinalUnitIndicationAvp fuiAvp = avpFactory.createFinalUnitIndication();
                fuiAvp.setFinalUnitAction(FinalUnitActionType.TERMINATE);
                ansMscc.setFinalUnitIndication(fuiAvp);
                ansMscc.setResultCode(resultCode);
            }
            ansMSCCs.add(ansMscc);
            ansMscc.setValidityTime(DEFAULT_VALIDITY_TIME);
        }
        answer.setMultipleServicesCreditControls(ansMSCCs.toArray(new MultipleServicesCreditControlAvp[ansMSCCs.size()]));
    }
    if (tracer.isInfoEnabled()) {
        tracer.info("[>>] " + sidString + " Created Credit-Control-Answer with Result-Code = " + answer.getResultCode() + ".");
        if (tracer.isFineEnabled()) {
            tracer.fine(answer.toString());
        }
    }
    return answer;
}
Also used : MultipleServicesCreditControlAvp(net.java.slee.resource.diameter.cca.events.avp.MultipleServicesCreditControlAvp) CreditControlInfo(org.mobicents.charging.server.account.CreditControlInfo) FinalUnitIndicationAvp(net.java.slee.resource.diameter.cca.events.avp.FinalUnitIndicationAvp) ArrayList(java.util.ArrayList) RoCreditControlAnswer(net.java.slee.resource.diameter.ro.events.RoCreditControlAnswer) GrantedServiceUnitAvp(net.java.slee.resource.diameter.cca.events.avp.GrantedServiceUnitAvp) CreditControlUnit(org.mobicents.charging.server.account.CreditControlUnit)

Example 2 with MultipleServicesCreditControlAvp

use of net.java.slee.resource.diameter.cca.events.avp.MultipleServicesCreditControlAvp in project jain-slee.diameter by RestComm.

the class CCAFactoriesTest method testAvpFactoryCreateMultipleServicesCreditControl.

@Test
public void testAvpFactoryCreateMultipleServicesCreditControl() throws Exception {
    String avpName = "Multiple-Services-Credit-Control";
    // Create AVP with mandatory values
    MultipleServicesCreditControlAvp msccAvp1 = ccaAvpFactory.createMultipleServicesCreditControl();
    // Make sure it's not null
    Assert.assertNotNull("Created " + avpName + " AVP from objects should not be null.", msccAvp1);
    // Create AVP with default constructor
    MultipleServicesCreditControlAvp msccAvp2 = ccaAvpFactory.createMultipleServicesCreditControl();
    // Should not contain mandatory values
    // Set mandatory values
    // Make sure it's equal to the one created with mandatory values constructor
    Assert.assertEquals("Created " + avpName + " AVP from default constructor + set<Mandatory-AVPs> should be equal to original.", msccAvp1, msccAvp2);
    // Make new copy
    msccAvp2 = ccaAvpFactory.createMultipleServicesCreditControl();
    // And set all values using setters
    CCAAvpAssistant.INSTANCE.testSetters(msccAvp2);
    // Create empty...
    MultipleServicesCreditControlAvp msccAvp3 = ccaAvpFactory.createMultipleServicesCreditControl();
    // Verify that no values have been set
    CCAAvpAssistant.INSTANCE.testHassers(msccAvp3, false);
    // Set all previous values
    msccAvp3.setExtensionAvps(msccAvp2.getExtensionAvps());
    // Verify if values have been set
    CCAAvpAssistant.INSTANCE.testHassers(msccAvp3, true);
    // Verify if values have been correctly set
    CCAAvpAssistant.INSTANCE.testGetters(msccAvp3);
    // Make sure they match!
    Assert.assertEquals("Created " + avpName + " AVP from default constructor + setUnitValue should be equal to original.", msccAvp2, msccAvp3);
}
Also used : MultipleServicesCreditControlAvp(net.java.slee.resource.diameter.cca.events.avp.MultipleServicesCreditControlAvp) Test(org.junit.Test) BaseFactoriesTest(org.mobicents.slee.resource.diameter.base.tests.factories.BaseFactoriesTest)

Example 3 with MultipleServicesCreditControlAvp

use of net.java.slee.resource.diameter.cca.events.avp.MultipleServicesCreditControlAvp in project smscgateway by RestComm.

the class ChargingSbb method setupChargingRequestInterface.

// public void onActivityEndEvent(ActivityEndEvent event, ActivityContextInterface aci) {
// logger.info(" Activity Ended[" + aci.getActivity() + "]");
// }
// Setup charging request
public void setupChargingRequestInterface(ChargingMedium chargingType, Sms sms) {
    if (logger.isFineEnabled()) {
        logger.fine("ChargingSbb: received message for process charging process: chargingType=" + chargingType + ", message=[" + sms + "]");
    }
    ChargingData chargingData = new ChargingData();
    chargingData.setSms(sms);
    chargingData.setChargingType(chargingType);
    this.setChargingData(chargingData);
    String sourceAddress = sms.getSourceAddr();
    int sourceTon = sms.getSourceAddrTon();
    String originatorSccpAddress = sms.getOriginatorSccpAddress();
    String origMoServiceCentreAddressDA = sms.getOrigMoServiceCentreAddressDA();
    if (origMoServiceCentreAddressDA == null) {
        origMoServiceCentreAddressDA = smscPropertiesManagement.getServiceCenterGt(sms.getSmsSet().getNetworkId());
    }
    String recipientAddress = sms.getSmsSet().getDestAddr();
    int destTon = sms.getSmsSet().getDestAddrTon();
    int dataCodingScheme = sms.getDataCoding();
    String interfaceId = Integer.toString(sms.getSmsSet().getNetworkId());
    String interfaceText = sms.getOrigEsmeName();
    try {
        DiameterIdentity destHost = null;
        if (smscPropertiesManagement.getDiameterDestHost() != null && !smscPropertiesManagement.getDiameterDestHost().equals("")) {
            // destHost = new DiameterIdentity("aaa://" +
            // smscPropertiesManagement.getDiameterDestHost() + ":" +
            // smscPropertiesManagement.getDiameterDestPort());
            destHost = new DiameterIdentity(smscPropertiesManagement.getDiameterDestHost());
        }
        DiameterIdentity destRealm = new DiameterIdentity(smscPropertiesManagement.getDiameterDestRealm());
        RoClientSessionActivity activity = this.roProvider.createRoClientSessionActivity(destHost, destRealm);
        ActivityContextInterface roACI = acif.getActivityContextInterface(activity);
        roACI.attach(getSbbContext().getSbbLocalObject());
        RoCreditControlRequest ccr = activity.createRoCreditControlRequest(CcRequestType.EVENT_REQUEST);
        // ccr.setDestinationRealm(destRealm);
        // ccr.setAuthApplicationId(APPLICATION_ID_OF_THE_DIAMETER_CREDIT_CONTROL_APPLICATION);
        ccr.setServiceContextId(SERVICE_CONTEXT_ID_SMSC);
        ccr.setCcRequestNumber(0);
        // ((SipUri)fromHeader.getAddress().getURI()).getUser();
        if (smscPropertiesManagement.getDiameterUserName() != null && !smscPropertiesManagement.getDiameterUserName().equals("")) {
            ccr.setUserName(smscPropertiesManagement.getDiameterUserName());
        }
        // This field contains the state associated to the CTF
        // do not know how to use it
        // a monotonically increasing value that is advanced whenever a
        // Diameter
        // entity restarts with loss of previous state, for example upon
        // reboot
        // ccr.setOriginStateId(smscRebootStep);
        // do not know if we need it
        ccr.setEventTimestamp(Calendar.getInstance().getTime());
        SubscriptionIdAvp subId = avpFactory.createSubscriptionId(SubscriptionIdType.END_USER_E164, sourceAddress);
        ccr.setSubscriptionId(subId);
        ccr.setRequestedAction(RequestedActionType.DIRECT_DEBITING);
        // ccr.setMultipleServicesIndicator(MultipleServicesIndicatorType.MULTIPLE_SERVICES_NOT_SUPPORTED);
        // requested units
        int messageCount = 1;
        int serviceIdentifier = 1;
        MultipleServicesCreditControlAvp multipleServicesCreditControl = avpFactory.createMultipleServicesCreditControl();
        RequestedServiceUnitAvp requestedServiceUnit = avpFactory.createRequestedServiceUnit();
        requestedServiceUnit.setCreditControlServiceSpecificUnits(messageCount);
        multipleServicesCreditControl.setRequestedServiceUnit(requestedServiceUnit);
        multipleServicesCreditControl.setServiceIdentifier(serviceIdentifier);
        ccr.setMultipleServicesCreditControl(multipleServicesCreditControl);
        // RequestedServiceUnitAvp RSU =
        // avpFactory.createRequestedServiceUnit();
        // RSU.setCreditControlTime(_FIRST_CHARGE_TIME);
        // ccr.setRequestedServiceUnit(RSU);
        // ServiceInformation - SMS info 2000
        ArrayList<DiameterAvp> smsInfoAvpLst = new ArrayList<DiameterAvp>();
        int vendorID = 10415;
        // Originator-SCCP-Address 2008
        if (originatorSccpAddress != null) {
            byte[] originatorSccpAddressAddrPartByteArr = originatorSccpAddress.getBytes(utf8Charset);
            byte[] originatorSccpAddressByteArr = new byte[2 + originatorSccpAddressAddrPartByteArr.length];
            originatorSccpAddressByteArr[1] = 8;
            System.arraycopy(originatorSccpAddressAddrPartByteArr, 0, originatorSccpAddressByteArr, 2, originatorSccpAddressAddrPartByteArr.length);
            DiameterAvp avpOriginatorSccpAddress = avpFactory.getBaseFactory().createAvp(vendorID, 2008, originatorSccpAddressByteArr);
            smsInfoAvpLst.add(avpOriginatorSccpAddress);
        }
        // SMSC-Address 2017
        if (origMoServiceCentreAddressDA != null) {
            byte[] origMoServiceCentreAddressDAPartByteArr = origMoServiceCentreAddressDA.getBytes(utf8Charset);
            byte[] origMoServiceCentreAddressDAByteArr = new byte[2 + origMoServiceCentreAddressDAPartByteArr.length];
            origMoServiceCentreAddressDAByteArr[1] = 8;
            System.arraycopy(origMoServiceCentreAddressDAPartByteArr, 0, origMoServiceCentreAddressDAByteArr, 2, origMoServiceCentreAddressDAPartByteArr.length);
            DiameterAvp avpOrigMoServiceCentreAddressDA = avpFactory.getBaseFactory().createAvp(vendorID, 2017, origMoServiceCentreAddressDAByteArr);
            smsInfoAvpLst.add(avpOrigMoServiceCentreAddressDA);
        }
        // Data-Coding-Scheme 2001
        DiameterAvp avpDataCodingScheme = avpFactory.getBaseFactory().createAvp(vendorID, 2001, dataCodingScheme);
        smsInfoAvpLst.add(avpDataCodingScheme);
        // SM-Message-Type 2007
        DiameterAvp avpSmMessageType = avpFactory.getBaseFactory().createAvp(vendorID, 2007, SmMessageTypeEnum.SUBMISSION.getValue());
        smsInfoAvpLst.add(avpSmMessageType);
        // Originator-Interface 2009
        ArrayList<DiameterAvp> originatorInterfaceAvpLst = new ArrayList<DiameterAvp>();
        DiameterAvp avpInterfaceId = avpFactory.getBaseFactory().createAvp(vendorID, 2003, interfaceId);
        originatorInterfaceAvpLst.add(avpInterfaceId);
        if (interfaceText != null) {
            DiameterAvp avpInterfaceText = avpFactory.getBaseFactory().createAvp(vendorID, 2005, interfaceText);
            originatorInterfaceAvpLst.add(avpInterfaceText);
        }
        DiameterAvp[] originatorInterfaceAvpArr = new DiameterAvp[originatorInterfaceAvpLst.size()];
        originatorInterfaceAvpLst.toArray(originatorInterfaceAvpArr);
        DiameterAvp avpOriginatorInterface = avpFactory.getBaseFactory().createAvp(vendorID, 2009, originatorInterfaceAvpArr);
        smsInfoAvpLst.add(avpOriginatorInterface);
        // Recipient-Address 1201
        ArrayList<DiameterAvp> recipientAddressAvpLst = new ArrayList<DiameterAvp>();
        DiameterAvp avpAddressType;
        if (destTon == 1)
            avpAddressType = avpFactory.getBaseFactory().createAvp(vendorID, 899, AddressTypeEnum.Msisdn.getValue());
        else
            avpAddressType = avpFactory.getBaseFactory().createAvp(vendorID, 899, AddressTypeEnum.Others.getValue());
        recipientAddressAvpLst.add(avpAddressType);
        DiameterAvp avpAddressData = avpFactory.getBaseFactory().createAvp(vendorID, 897, recipientAddress);
        recipientAddressAvpLst.add(avpAddressData);
        DiameterAvp[] recipientAddressAvpArr = new DiameterAvp[recipientAddressAvpLst.size()];
        recipientAddressAvpLst.toArray(recipientAddressAvpArr);
        DiameterAvp avpRecipientAddress = avpFactory.getBaseFactory().createAvp(vendorID, 1201, recipientAddressAvpArr);
        // Recipient-Info 2026
        ArrayList<DiameterAvp> recipientInfoAvpLst = new ArrayList<DiameterAvp>();
        recipientInfoAvpLst.add(avpRecipientAddress);
        DiameterAvp[] recipientInfoAvpArr = new DiameterAvp[recipientInfoAvpLst.size()];
        recipientInfoAvpLst.toArray(recipientInfoAvpArr);
        DiameterAvp avpRecipientInfo = avpFactory.getBaseFactory().createAvp(vendorID, 2026, recipientInfoAvpArr);
        smsInfoAvpLst.add(avpRecipientInfo);
        // Originator-Received-Address 2027
        ArrayList<DiameterAvp> originatorReceivedAddressAvpLst = new ArrayList<DiameterAvp>();
        if (sourceTon == 1)
            avpAddressType = avpFactory.getBaseFactory().createAvp(vendorID, 899, AddressTypeEnum.Msisdn.getValue());
        else
            avpAddressType = avpFactory.getBaseFactory().createAvp(vendorID, 899, AddressTypeEnum.Others.getValue());
        originatorReceivedAddressAvpLst.add(avpAddressType);
        avpAddressData = avpFactory.getBaseFactory().createAvp(vendorID, 897, sourceAddress);
        originatorReceivedAddressAvpLst.add(avpAddressData);
        DiameterAvp[] originatorReceivedAddressAvpArr = new DiameterAvp[originatorReceivedAddressAvpLst.size()];
        originatorReceivedAddressAvpLst.toArray(originatorReceivedAddressAvpArr);
        DiameterAvp avpOriginatorReceivedAddress = avpFactory.getBaseFactory().createAvp(vendorID, 2027, originatorReceivedAddressAvpArr);
        smsInfoAvpLst.add(avpOriginatorReceivedAddress);
        // final assembling
        DiameterAvp[] smsInfoAvpArr = new DiameterAvp[smsInfoAvpLst.size()];
        smsInfoAvpLst.toArray(smsInfoAvpArr);
        DiameterAvp[] smsInfo = new DiameterAvp[1];
        smsInfo[0] = avpFactory.getBaseFactory().createAvp(vendorID, 2000, smsInfoAvpArr);
        ServiceInformation si = avpFactory.createServiceInformation();
        si.setExtensionAvps(smsInfo);
        ccr.setServiceInformation(si);
        activity.sendEventRoCreditControlRequest(ccr);
        if (logger.isFineEnabled()) {
            logger.fine("Sent INITIAL CCR: " + ccr);
        }
        // set new timer for the case we will not get CCA in time
        timerFacility.setTimer(roACI, null, System.currentTimeMillis() + (CCR_TIMEOUT * 1000), defaultTimerOptions);
    } catch (Exception e1) {
        logger.severe("setupChargingRequestInterface(): error while sending RoCreditControlRequest: " + e1.getMessage(), e1);
        generateCDR(sms, CdrGenerator.CDR_SUBMIT_FAILED_CHARGING, e1.getMessage(), false, true);
    }
}
Also used : MultipleServicesCreditControlAvp(net.java.slee.resource.diameter.cca.events.avp.MultipleServicesCreditControlAvp) ActivityContextInterface(javax.slee.ActivityContextInterface) ArrayList(java.util.ArrayList) RoClientSessionActivity(net.java.slee.resource.diameter.ro.RoClientSessionActivity) RoCreditControlRequest(net.java.slee.resource.diameter.ro.events.RoCreditControlRequest) SubscriptionIdAvp(net.java.slee.resource.diameter.cca.events.avp.SubscriptionIdAvp) SmscProcessingException(org.mobicents.smsc.library.SmscProcessingException) CreateException(javax.slee.CreateException) PersistenceException(org.mobicents.smsc.cassandra.PersistenceException) ServiceInformation(net.java.slee.resource.diameter.ro.events.avp.ServiceInformation) DiameterIdentity(net.java.slee.resource.diameter.base.events.avp.DiameterIdentity) DiameterAvp(net.java.slee.resource.diameter.base.events.avp.DiameterAvp) RequestedServiceUnitAvp(net.java.slee.resource.diameter.cca.events.avp.RequestedServiceUnitAvp)

Example 4 with MultipleServicesCreditControlAvp

use of net.java.slee.resource.diameter.cca.events.avp.MultipleServicesCreditControlAvp in project charging-server by RestComm.

the class DiameterChargingServerSbb method onCreditControlRequest.

public void onCreditControlRequest(RoCreditControlRequest ccr, ActivityContextInterface aci) {
    String serviceContextId = "Some-Service-Context-Id";
    String sessionId = ccr.getSessionId();
    UserSessionInfo sessionInfo = getSessionInfo();
    if (sessionInfo == null) {
        sessionInfo = new UserSessionInfo();
        sessionInfo.setSessionStartTime(System.currentTimeMillis());
    }
    sessionInfo.setCcr(ccr);
    sessionInfo.setSessionId(sessionId);
    setSessionInfo(sessionInfo);
    String reqType = ccr.getCcRequestType().toString();
    long reqNumber = ccr.getCcRequestNumber();
    sidString = "SID<" + limitString(sessionId, 9, 9, "..") + "/" + reqType.substring(0, 3) + "#" + reqNumber + ">";
    if (tracer.isInfoEnabled()) {
        tracer.info("[<<] " + sidString + " Received Credit-Control-Request [" + reqType + "]");
        if (tracer.isFineEnabled()) {
            tracer.fine(ccr.toString());
        }
    }
    // Some common ops. may be moved to proper places to avoid unnecessary ops
    RoServerSessionActivity ccServerActivity = (RoServerSessionActivity) aci.getActivity();
    SubscriptionIdType endUserType = null;
    String endUserId = null;
    // Get the Subscription-Id and it's Type .. for now we only care for first, still we log all
    SubscriptionIdAvp[] subscriptionIds = ccr.getSubscriptionIds();
    RoCreditControlAnswer cca = null;
    if (subscriptionIds != null && subscriptionIds.length > 0) {
        endUserType = subscriptionIds[0].getSubscriptionIdType();
        endUserId = subscriptionIds[0].getSubscriptionIdData();
        if (tracer.isFineEnabled()) {
            String subsIdsStr = "";
            for (SubscriptionIdAvp subscriptionId : subscriptionIds) {
                subsIdsStr += subscriptionId.getSubscriptionIdType() + "=" + subscriptionId.getSubscriptionIdData() + " ";
            }
            tracer.fine("[--] " + sidString + " Received CCR has Subcription-Id(s): " + subsIdsStr.substring(0, subsIdsStr.length() - 1));
        }
    } else {
        tracer.severe("[xx] " + sidString + " Subscription-Id AVP missing in CCR. Rejecting CCR.");
        cca = createCCA(ccServerActivity, ccr, null, DiameterResultCode.DIAMETER_MISSING_AVP);
        sendCCA(cca, aci, true);
        return;
    }
    if (endUserId == null) {
        tracer.severe("[xx] " + sidString + " Subscription-Id AVP is present but could not read it's data. Rejecting CCR.");
        cca = createCCA(ccServerActivity, ccr, null, DiameterResultCode.DIAMETER_MISSING_AVP);
        sendCCA(cca, aci, true);
        return;
    }
    // Retrieve child SBBs
    try {
        accountBalanceManagement = getAccountManager();
        ratingEngineManagement = getRatingEngineManager();
        cdrGenerator = getCDRGenerator();
    } catch (Exception e) {
        // TODO: By configuration it should be possible to proceed
        tracer.severe("[xx] " + sidString + " Unable to retrieve Account & Balance Management or Rating Child SBB. Unable to continue.", e);
        cca = createCCA(ccServerActivity, ccr, new ArrayList<CreditControlInfo>(), DiameterResultCode.DIAMETER_UNABLE_TO_COMPLY);
        sendCCA(cca, aci, true);
    }
    switch(ccr.getCcRequestType()) {
        // INITIAL_REQUEST 1
        case INITIAL_REQUEST:
        // UPDATE_REQUEST 2
        case UPDATE_REQUEST:
            try {
                // retrieve service information from AVPs
                serviceContextId = ccr.getServiceContextId();
                if (serviceContextId == null) {
                    tracer.severe("[xx] " + sidString + " Service-Context-Id AVP missing in CCR. Rejecting CCR.");
                    // TODO: include missing avp - its a "SHOULD"
                    cca = createCCA(ccServerActivity, ccr, null, DiameterResultCode.DIAMETER_MISSING_AVP);
                    sendCCA(cca, aci, true);
                } else {
                    if (serviceContextId.equals("")) {
                        tracer.severe("[xx] " + sidString + " Service-Context-Id AVP is empty in CCR. Rejecting CCR.");
                        cca = createCCA(ccServerActivity, ccr, null, DiameterResultCode.DIAMETER_INVALID_AVP_VALUE);
                        sendCCA(cca, aci, true);
                    }
                }
                // TODO: For Ro, support Service-Information AVP
                List<CreditControlInfo> reservations = new ArrayList<CreditControlInfo>();
                long resultCode = DiameterResultCode.DIAMETER_SUCCESS;
                MultipleServicesCreditControlAvp[] multipleServicesCreditControlAvps = ccr.getMultipleServicesCreditControls();
                if (multipleServicesCreditControlAvps != null && tracer.isFineEnabled()) {
                    tracer.fine("[--] " + sidString + " Received CCR has Multiple-Services-Credit-Control AVP with length = " + multipleServicesCreditControlAvps.length);
                }
                // If there's no MSCC AVP, we'll create one, just to go inside the for and have it processed..
                if (multipleServicesCreditControlAvps.length == 0) {
                    MultipleServicesCreditControlAvp fakeMSCC = avpFactory.createMultipleServicesCreditControl();
                    fakeMSCC.setServiceIdentifier(0);
                    RequestedServiceUnitAvp rsu = avpFactory.createRequestedServiceUnit();
                    rsu.setCreditControlTotalOctets(0);
                    fakeMSCC.setRequestedServiceUnit(rsu);
                    multipleServicesCreditControlAvps = new MultipleServicesCreditControlAvp[] { fakeMSCC };
                }
                // single rating group.
                for (MultipleServicesCreditControlAvp mscc : multipleServicesCreditControlAvps) {
                    // The Service-Identifier and the Rating-Group AVPs are used to associate the granted units to a
                    // given service or rating group.  If both the Service-Identifier and the Rating-Group AVPs are
                    // included, the target of the service units is always the service(s) indicated by the value of the
                    // Service-Identifier AVP(s).  If only the Rating-Group-Id AVP is present, the Multiple-Services-
                    // -Credit-Control AVP relates to all the services that belong to the specified rating group.
                    long ratingGroup = mscc.getRatingGroup();
                    long[] serviceIds = mscc.getServiceIdentifiers();
                    // The Requested-Service-Unit AVP MAY contain the amount of requested service units [...]. It MUST
                    // be present in the initial interrogation and within the intermediate interrogations in which new
                    // quota is requested.  If the credit-control client does not include the Requested-Service-Unit AVP
                    // in a request command, because for instance, it has determined that the end-user terminated the
                    // service, the server MUST debit the used amount from the user's account but MUST NOT return a new
                    // quota in the corresponding answer.
                    RequestedServiceUnitAvp rsu = mscc.getRequestedServiceUnit();
                    ArrayList<CreditControlUnit> ccUnits = getRequestedUnits(ccr, rsu, serviceIds);
                    // if its UPDATE, lets first update data
                    if (ccr.getCcRequestType() == CcRequestType.UPDATE_REQUEST) {
                        // update used units for each CC-Type.
                        UsedServiceUnitAvp[] usedUnitsAvps = mscc.getUsedServiceUnits();
                        sessionInfo = getSessionInfo();
                        CreditControlInfo reservedInfo = sessionInfo.getReservations().get(sessionInfo.getReservations().size() - 1);
                        ArrayList<CreditControlUnit> usedCCUnits = collectUsedUnits(usedUnitsAvps, reservedInfo.getCcUnits());
                        // Merge Requested with Used/Reserved CC Units into a single CCUnits
                        ccUnits.addAll(usedCCUnits);
                        // Call ABMF with this Credit Control Info
                        CreditControlInfo ccInfo = buildCCInfo(ccr, endUserId, endUserType, ccUnits);
                        accountBalanceManagement.updateRequest(ccInfo);
                    } else {
                        // Initial Request
                        // Call ABMF with this Credit Control Info
                        CreditControlInfo ccInfo = buildCCInfo(ccr, endUserId, endUserType, ccUnits);
                        accountBalanceManagement.initialRequest(ccInfo);
                    }
                    // Store Credit Control Info in CMP
                    sessionInfo = getSessionInfo();
                    sessionInfo.setCcr(ccr);
                    sessionInfo.setServiceIds(serviceIds);
                    sessionInfo.setEndUserId(endUserId);
                    sessionInfo.setEndUserType(endUserType);
                    setSessionInfo(sessionInfo);
                    // we'll continue @ resumeOnCreditControlRequest(..)
                    return;
                }
                if (reservations.size() > 0) {
                    cca = createCCA(ccServerActivity, ccr, reservations, resultCode);
                } else {
                    cca = createCCA(ccServerActivity, ccr, null, DiameterResultCode.DIAMETER_MISSING_AVP);
                }
                sendCCA(cca, aci, false);
            } catch (Exception e) {
                tracer.severe("[xx] " + sidString + " Failure processing Credit-Control-Request [" + (ccr.getCcRequestType() == CcRequestType.INITIAL_REQUEST ? "INITIAL" : "UPDATE") + "]", e);
            }
            break;
        // TERMINATION_REQUEST 3
        case TERMINATION_REQUEST:
            try {
                if (tracer.isInfoEnabled()) {
                    tracer.info("[>>] " + sidString + " '" + endUserId + "' requested service termination for '" + serviceContextId + "'.");
                }
                for (MultipleServicesCreditControlAvp mscc : ccr.getMultipleServicesCreditControls()) {
                    UsedServiceUnitAvp[] usedUnitsAvps = mscc.getUsedServiceUnits();
                    sessionInfo = getSessionInfo();
                    CreditControlInfo reservedInfo = sessionInfo.getReservations().get(sessionInfo.getReservations().size() - 1);
                    ArrayList<CreditControlUnit> ccUnits = collectUsedUnits(usedUnitsAvps, reservedInfo.getCcUnits());
                    // Call ABMF with this Credit Control Info
                    CreditControlInfo ccInfo = buildCCInfo(ccr, endUserId, endUserType, ccUnits);
                    accountBalanceManagement.terminateRequest(ccInfo);
                    // we'll continue @ resumeOnCreditControlRequest(..)
                    return;
                }
                // 8.7.  Cost-Information AVP
                // 
                // The Cost-Information AVP (AVP Code 423) is of type Grouped, and it is
                // used to return the cost information of a service, which the credit-
                // control client can transfer transparently to the end user.  The
                // included Unit-Value AVP contains the cost estimate (always type of
                // money) of the service, in the case of price enquiry, or the
                // accumulated cost estimation, in the case of credit-control session.
                // 
                // The Currency-Code specifies in which currency the cost was given.
                // The Cost-Unit specifies the unit when the service cost is a cost per
                // unit (e.g., cost for the service is $1 per minute).
                // 
                // When the Requested-Action AVP with value PRICE_ENQUIRY is included in
                // the Credit-Control-Request command, the Cost-Information AVP sent in
                // the succeeding Credit-Control-Answer command contains the cost
                // estimation of the requested service, without any reservation being
                // made.
                // 
                // The Cost-Information AVP included in the Credit-Control-Answer
                // command with the CC-Request-Type set to UPDATE_REQUEST contains the
                // accumulated cost estimation for the session, without taking any
                // credit reservation into account.
                // 
                // The Cost-Information AVP included in the Credit-Control-Answer
                // command with the CC-Request-Type set to EVENT_REQUEST or
                // TERMINATION_REQUEST contains the estimated total cost for the
                // requested service.
                // 
                // It is defined as follows (per the grouped-avp-def of
                // RFC 3588 [DIAMBASE]):
                // 
                // Cost-Information ::= < AVP Header: 423 >
                // { Unit-Value }
                // { Currency-Code }
                // [ Cost-Unit ]
                // 7.2.133 Remaining-Balance AVP
                // 
                // The Remaining-Balance AVP (AVPcode 2021) is of type Grouped and
                // provides information about the remaining account balance of the
                // subscriber.
                // 
                // It has the following ABNF grammar:
                // Remaining-Balance :: =  < AVP Header: 2021 >
                // { Unit-Value }
                // { Currency-Code }
                // We use no money notion ... maybe later.
                // AvpSet costInformation = ccaAvps.addGroupedAvp(423);
                // Answer with DIAMETER_SUCCESS, since "4) The default action for failed operations should be to terminate the data session"
                // its terminated, we cant do much here...
                cca = createCCA(ccServerActivity, ccr, null, DiameterResultCode.DIAMETER_SUCCESS);
                sendCCA(cca, aci, true);
            } catch (Exception e) {
                tracer.severe("[xx] " + sidString + " Failure processing Credit-Control-Request [TERMINATION]", e);
            }
            break;
        // EVENT_REQUEST 4
        case EVENT_REQUEST:
            try {
                RequestedActionType reqAction = ccr.getRequestedAction();
                if (tracer.isInfoEnabled()) {
                    tracer.info("[<<] " + sidString + " Received Credit-Control-Request [EVENT] with Requested-Action [" + reqAction + "]");
                    if (tracer.isFineEnabled()) {
                        tracer.fine(ccr.toString());
                    }
                }
                if (reqAction == null) {
                    tracer.severe("[xx] " + sidString + " Unable to retrieve Requested-Action AVP. Replying with MISSING_AVP.");
                    createCCA(ccServerActivity, ccr, new ArrayList<CreditControlInfo>(), DiameterResultCode.DIAMETER_MISSING_AVP);
                    sendCCA(cca, aci, true);
                } else if (reqAction == RequestedActionType.DIRECT_DEBITING) {
                    for (MultipleServicesCreditControlAvp mscc : ccr.getMultipleServicesCreditControls()) {
                        RequestedServiceUnitAvp rsu = mscc.getRequestedServiceUnit();
                        long[] serviceIds = mscc.getServiceIdentifiers();
                        ArrayList<CreditControlUnit> ccUnits = getRequestedUnits(ccr, rsu, serviceIds);
                        // Call ABMF with this Credit Control Info
                        CreditControlInfo ccInfo = buildCCInfo(ccr, endUserId, endUserType, ccUnits);
                        accountBalanceManagement.eventRequest(ccInfo);
                        // Store Credit Control Info in CMP
                        sessionInfo = getSessionInfo();
                        sessionInfo.setCcr(ccr);
                        sessionInfo.setEndUserId(endUserId);
                        // sessionInfo.getReservations().add(ccInfo);
                        setSessionInfo(sessionInfo);
                        if (tracer.isInfoEnabled()) {
                            tracer.info(sessionInfo.toString());
                        }
                        // we'll continue @ resumeOnCreditControlRequest(..)
                        return;
                    }
                } else {
                    tracer.severe("[xx] " + sidString + " Unsupported Requested-Action AVP (" + reqAction + "). Replying with DIAMETER_UNABLE_TO_COMPLY.");
                    createCCA(ccServerActivity, ccr, new ArrayList<CreditControlInfo>(), DiameterResultCode.DIAMETER_UNABLE_TO_COMPLY);
                    sendCCA(cca, aci, true);
                }
            } catch (Exception e) {
                tracer.severe("[xx] " + sidString + " Failure processing Credit-Control-Request [EVENT]", e);
            }
            break;
        default:
            tracer.warning("[xx] " + sidString + " Unknown request type found!");
            break;
    }
}
Also used : MultipleServicesCreditControlAvp(net.java.slee.resource.diameter.cca.events.avp.MultipleServicesCreditControlAvp) RoServerSessionActivity(net.java.slee.resource.diameter.ro.RoServerSessionActivity) ArrayList(java.util.ArrayList) RequestedActionType(net.java.slee.resource.diameter.cca.events.avp.RequestedActionType) SubscriptionIdAvp(net.java.slee.resource.diameter.cca.events.avp.SubscriptionIdAvp) CreateException(javax.slee.CreateException) IOException(java.io.IOException) SLEEException(javax.slee.SLEEException) UsedServiceUnitAvp(net.java.slee.resource.diameter.cca.events.avp.UsedServiceUnitAvp) UserSessionInfo(org.mobicents.charging.server.data.UserSessionInfo) CreditControlUnit(org.mobicents.charging.server.account.CreditControlUnit) CreditControlInfo(org.mobicents.charging.server.account.CreditControlInfo) SubscriptionIdType(net.java.slee.resource.diameter.cca.events.avp.SubscriptionIdType) RoCreditControlAnswer(net.java.slee.resource.diameter.ro.events.RoCreditControlAnswer) RequestedServiceUnitAvp(net.java.slee.resource.diameter.cca.events.avp.RequestedServiceUnitAvp)

Aggregations

MultipleServicesCreditControlAvp (net.java.slee.resource.diameter.cca.events.avp.MultipleServicesCreditControlAvp)4 ArrayList (java.util.ArrayList)3 CreateException (javax.slee.CreateException)2 RequestedServiceUnitAvp (net.java.slee.resource.diameter.cca.events.avp.RequestedServiceUnitAvp)2 SubscriptionIdAvp (net.java.slee.resource.diameter.cca.events.avp.SubscriptionIdAvp)2 RoCreditControlAnswer (net.java.slee.resource.diameter.ro.events.RoCreditControlAnswer)2 CreditControlInfo (org.mobicents.charging.server.account.CreditControlInfo)2 CreditControlUnit (org.mobicents.charging.server.account.CreditControlUnit)2 IOException (java.io.IOException)1 ActivityContextInterface (javax.slee.ActivityContextInterface)1 SLEEException (javax.slee.SLEEException)1 DiameterAvp (net.java.slee.resource.diameter.base.events.avp.DiameterAvp)1 DiameterIdentity (net.java.slee.resource.diameter.base.events.avp.DiameterIdentity)1 FinalUnitIndicationAvp (net.java.slee.resource.diameter.cca.events.avp.FinalUnitIndicationAvp)1 GrantedServiceUnitAvp (net.java.slee.resource.diameter.cca.events.avp.GrantedServiceUnitAvp)1 RequestedActionType (net.java.slee.resource.diameter.cca.events.avp.RequestedActionType)1 SubscriptionIdType (net.java.slee.resource.diameter.cca.events.avp.SubscriptionIdType)1 UsedServiceUnitAvp (net.java.slee.resource.diameter.cca.events.avp.UsedServiceUnitAvp)1 RoClientSessionActivity (net.java.slee.resource.diameter.ro.RoClientSessionActivity)1 RoServerSessionActivity (net.java.slee.resource.diameter.ro.RoServerSessionActivity)1