The Ro Raw API is a more flexible method to send custom session and event requests that require more knowledge of the underlying protocol.
The sendCCRaw() Web service allows the developer using this method to completely control the order, type, and content of each AVP to be included in the Diameter Credit Control Request (CCR). These AVPs can be defined by the IETF, the 3GPP, or by any other vendor. The difference is that the application server application must construct an array of these AVPs before invoking the sendCCRaw() method.
When the sendCCRaw() Web service returns, the value returned is an array of the AVPs received from the Online Charging System (OCS) in the Credit Control Answer (CCA) packet. It is then up to the Application Server Application to parse the AVP array and retrieve any of the information that it requires.
The sendCCRaw() Web service is largely a pass-through method. It encapsulates the array of AVPs in the request and places them in a Diameter CCR frame. When the CCA is received, it extracts the AVPs from the CCA, places them into an array, and returns them to the caller. There is very little checking performed by the sendCCRaw() Web service.
Contained within the AVP header, the AVP Code in combination with the Vendor-ID (if present) uniquely identifies the AVP. AVPs defined in the base specification (RFC 3588) do not contain Vendor-IDs and AVPs defined by the 3GPP use a Vendor-ID of 10415. The AVP flags (VMPrrrrr) further classify the AVP. If the V(endor-Specific) bit is set, the AVP is defined by a vendor other than the IETF. If the M(andatory) bit is set, the AVP MUST be understood by the Diameter peer. The P bit is an obsolete security bit, and should always be zero.
These are fairly self explanatory based on their names. For example, the AvpValueUtilUnsigned32 contains a 32 bit integer. However, the actual value in java is signed, so you must exercise care in using the value especially if you are performing arithmetic with it. You would need to take the hex value and convert it to a long through a logic operations such as an 'AND'.
There are a two AVP types that need some elaboration. The first is the Grouped AVP. Any time the AVP you are using is of type Grouped, it contains other AVPs. The AvpValueUtilGrouped helper class contains a vector of AVPs.
The other AVP type is AvpValueUtilUnknown. This AVP type is used by the Diameter Enabler when it is attempting to parse the data stream, but does not know the definition for a given AVP. A case when this might happen is when a server defines its own, custom Vendor Specific AVP outside of the IETF or 3GPP. The Diameter Enabler, when it receives an AVP that it does not recognize will store all of the data for that AVP as a byte array or octet string. So, if the custom AVP was of type unsigned 32, then the Diameter Enabler would read it in to array with a length of 4 bytes and place this value in an AvpValueUtilUnknown object in the AVP.
Thus, when you are using the Raw interface to create a custom frame and expect to receive back custom AVPs. The AVPs unknown to the Diameter Enabler will have AvpValueUtilUnknown values in them. The application must then convert that byte array to the appropriate type.
Any AVP that is unknown to the Diameter Enabler will receive this handling including custom Grouped AVPs. Even if some of the AVPs that a Grouped AVP holds are known to the Diameter Enabler, they will be included as data in the byte array that contains the payload of the owning Grouped AVP.
For more information on the helper classes and their methods, refer to the Javadoc. These classes are provided as part of the IMS Connector CD. They are also included in the IMS Tooling packages associated with the IMS Connector.
Avp originRealmAvp = AvpFactory.createOriginRealmAvp("asclient.example.com");
Avp exponentAvp = ChargingAvpFactory.createExponentAvp(2);
The AVPs that you are able to create using the AvpFactory and ChargingAvpFactory are limited to those defined by the Diameter Enabler. You may want to create your own AVPs that are not included in the Diameter Enabler.
AvpValueUtil numberOfMembersValueUtil = new AvpValueUtilUnsigned32(20); Avp numberOfMembersAvp = new VsAvp(NUMBER_OF_MEMBERS, Avp.VON_MON_POFF,numberOfMembersValueUtil, VENDOR_ID_COMPANYX);
This example creates a new vendor-specific AVP of type Unsigned32 and loads it with a value of 20. It also creates the AVP with the V-bit (vendor -specific) set to 1, the M-bit (Mandatory) set to 1, and the P-bit set to 0. Finally, the Vendor ID is set to COMPANYX's vendor ID. The vendor ID should be listed in the enterprise-numbers2 on the Internet Assigned Numbers Authority site.
You create AVPs when you wish to send a data element to the OCS. You receive back the AVPs that the OCS sends in its CCA. The result is returned in an Array of AVPs that occur in the order in which the AVPs were received with array[0] being the first AVP received. The type of data that is held within the AVP is either that defined by the IETF or 3GPP if the AVP is formally defined in the Ro definition. If the AVP is not in any of these definitions, then the data type will be AvpValueUtilUnknown.
Whenever you receive an AVP with data of type AvpValueUtilUnknown, the Diameter Enabler does not have a definition of the AVP in its dictionary. Your application must convert the byte array into data of a type that is usable by your application. Simple types, such as Unsigned32, are straight forward. However, the Grouped type means that AVPs including their AVP headers will be included in the byte array. And because there can be any number of nesting levels, Grouped AVPs will need some additional parsing algorithm to convert them from an array of bytes into an array of AVPs or other data elements.
In general, if you wish to retrieve information from the reply frame, you will walk through the list of AVPs received, pull the one of interest, get its AvpValueUtil, and invoke the getAvpValue() method of the AvpValueUtil.
If you create an AVP that is already defined by the Diameter Enabler, your AVP will be transmitted with the type, values, and AVP header bits that you have defined. However, if the same AVP is received by the Diameter Enabler in the reply, the Diameter Enabler's definition will be applied when creating the AVP.
Also, an incorrectly created AVP may affect the data stream and cause an Out-Of-Sync error to occur. If when transmitting, the number of bytes expected does not match the length parameters, the packet will be malformed. An error such as this may cause the other side of the connection to determine that it no longer knows where it is in the data stream. This generally results in the connection being dropped and re-established. For this reason, you need to secure and limit the access to these data services to trusted applications.
DiameterRoService_SEIServiceLocator locator = new DiameterRoService_SEIServiceLocator(); DiameterRoService_SEI service = locator.getDiameterRoService(endpoint); Avp[] avpArray = null; ArrayList avpArrayList = new ArrayList(); avpArrayList.add(AvpFactory.createSessionIdAvp("session1")); avpArrayList.add(AvpFactory.createOriginHostAvp("aaa://originhost.example.com;transport=tcp")); avpArrayList.add(AvpFactory.createOriginRealmAvp("aaa://example.com;transport=tcp")); avpArrayList.add(AvpFactory.createDestinationRealmAvp("example.example.com")); avpArrayList.add(AvpFactory.createDestinationHostAvp("aaa://host1.example.example.com;transport=tcp")); avpArrayList.add(AvpFactory.createAuthApplicationIdAvp(4)); // credit control application avpArrayList.add(createVSApplicationIdAvp()); // Grouped avpArrayList.add(ChargingAvpFactory.createServiceContextIdAvp("Video Share is vshare@example.com")); avpArrayList.add(AvpFactory.createEventTimestampAvp(System.currentTimeMillis())); avpArrayList.add(ChargingAvpFactory.createCcRequestTypeAvp(1)); // 1 = Initial avpArrayList.add(ChargingAvpFactory.createCcRequestNumberAvp(0)); // Initial CCR number = 0 avpArrayList.add(createSubscriptionIdAvp()); // Grouped avpArrayList.add(createImsInformationAvp()); // Grouped avpArray = avpArrayList.toArray(avpArray); //Send the Web Service Request Avp[] result = service.sendCCRaw(avpArray);