As I am currently doing a lot of research on IMS charging (online charging specifically), I am going through the 3GPP and IETF standards quite a lot. As critical engineer I usually tend to have some irritations or critiques. You’ll probably see me ‘venting’ this type of thing more often on this blog. Today’s irritation is a small limitation that I found the Ro specification. Well it’s actually just an opinion :). And perhaps I’m being just a bit picky, but why not go for perfection right?
The Remaining-Balance AVP can only occur once in a CCA. Furthermore, the assumption is made that balances can only be monetary. Is that all? Yes that’s all… But it is not consistent with the designs I expect for the counters managed by the Account Balance Management Function. Although the Rc reference point is not yet defined, the Re reference point specifications hints that a subscriber can have multiple balances/counters. This is hinted by the allowed occurrence of AVPs such as Counter, Counter-Price, Counter-Tariff and Impact-On-Counter. And it makes sense to me to have multiple balances! I need a monetary balance for pre-paid subscribers. But why shouldn’t we use the ABMF to manage things such as data quota’s, multimedia message quota’s, frequent caller bonus points, air-miles, and every thing else that can be counted for that matter! Of course this is still possible, only the OCS can never tell the UE about the current value of those balances through the Ro reference point. And all that can be fixed by adding an asterisk to the specifications
Frens Jan Rumph
I finished extracting the diameter specifications for the Re reference point some days ago. I’ve included my semi-proprietary ABNF specifications below.
Not as much work as the Ro reference point, but it took me a bit more time to get my head around it. Ro is pretty straightforward, a lot of it is thoroughly explained in IETF rfc 4006, and from the syntax specified in the 3GPP specs a lot of semantics can be pretty easily deduced.
Re however is a different story, the syntax is specified at an acceptable standard, but a lot of interpretation and even guessing is required to understand it fully. There are still semantics that I don’t feel 100% comfortable about.
An example: the relationship between the Monetary-Tariff AVP and the Counter-Tariff AVP. Does the existence of the Monetary-Tariff AVP mean that there can be only one monetary balance? Hopefully not, the existence of the Counter-Tariff AVP seems to indicate the opposite. However the Monetary-Tariff AVP is mandatory in the Service-Rating AVP, while the Counter-Tariff AVP is not. How should this be interpreted by an OCF?
Another example: I’m not really sure about how to interpret multiple occurrences of the Service-Rating AVP. That is most likely due to the fact that I am working on the concept of the Correlation Function a lot lately. The question is how to include the information from the correlation context … If this not done by include multiple Service-Rating AVP’s, then how? If it is done by including multiple Service-Rating AVP’s, then will all of them be rated? What will happen when using a “B”-class rating function?
Food for thought…
The Re specs (please note that the application and avp ids are To Be Determined):
PRQ ::= < Diameter Header: TBD, REQ, PXY, TBD >
< Session-Id >
{ Origin-Host }
{ Origin-Realm }
{ Destination-Realm }
[ Destination-Host ]
[ Vendor-Specific-Application-Id ]
[ User-Name ]
[ Event-Timestamp ]
{ Actual-Time }
{ Subscription-Id }
* { Service-Rating }
PRS ::= < Diameter Header: TBD, PXY, TBD >
< Session-Id >
{ Origin-Host }
{ Origin-Realm }
[ Vendor-Specific-Application-Id ]
[ User-Name ]
[ Event-Timestamp ]
* { Service-Rating }
TRQ ::= < Diameter Header: TBD, REQ, PXY, TBD >
< Session-Id >
{ Origin-Host }
{ Origin-Realm }
{ Destination-Realm }
[ Destination-Host ]
[ Vendor-Specific-Application-Id ]
[ User-Name ]
[ Event-Timestamp ]
[ First-Request ]
[ Begin-Time ]
{ Actual-Time }
{ Subscription-Id }
* { Service-Rating }
TRS ::= < Diameter Header: TBD, PXY, TBD >
< Session-Id >
{ Origin-Host }
{ Origin-Realm }
[ Vendor-Specific-Application-Id ]
[ User-Name ]
[ Event-Timestamp ]
* { Service-Rating }
SUQ ::= < Diameter Header: TBD, REQ, PXY, TBD >
< Session-Id >
{ Origin-Host }
{ Origin-Realm }
{ Destination-Realm }
[ Destination-Host ]
[ Vendor-Specific-Application-Id ]
[ User-Name ]
[ Event-Timestamp ]
[ Begin-Time ]
{ Actual-Time }
{ Subscription-Id }
* { Service-Rating }
SUS ::= < Diameter Header: TBD, PXY, TBD >
< Session-Id >
{ Origin-Host }
{ Origin-Realm }
[ Vendor-Specific-Application-Id ]
[ User-Name ]
[ Event-Timestamp ]
* { Service-Rating }
Counter ::= < AVP Header: TBD >
{ Counter-ID }
[ Counter-Value ]
[ Counter-Expiry-Date ]
Counter-Price ::= < AVP Header: TBD >
{ Counter-ID }
[ Counter-Type ]
[ Counter-Change ]
[ Set-Counter-To ]
[ Counter-Expiry-Date ]
Counter-Tariff ::= < AVP Header: TBD >
{ Counter-ID }
[ Counter-Type ]
[ Counter-Change-Per-Session ]
[ Counter-Change-Per-Consumed-Service-Unit ]
[ Counter-Change-For-First-Chargeable-Time-Unit ]
[ Counter-Change-Per-Subsequent-Chargeable-Time-Unit ]
[ Counter-Change-Per-Chargeable-Volume-Unit ]
[ Counter-Change-For-First-Chargeable-Time-Unit-After-Switch ]
[ Counter-Change-Per-Subsequent-Chargeable-Time-Unit-After-Switch ]
[ Counter-Change-Per-Chargeable-Volume-Unit-After-Switch ]
[ Counter-Threshold ]
[ Set-Counter-To ]
[ Counter-Expiry-Date ]
Destination-ID ::= < AVP Header: TBD >
{ Destination-ID-Type }
{ Destination-ID-Data }
Impact-On-Counter ::= < AVP Header: TBD >
{ Counter-ID }
[ Counter-Value-Begin ]
{ Counter-Value-Change }
[ Counter-Value-End ]
Monetary-Tariff ::= < AVP Header: TBD >
{ EParameter-E1 }
{ EParameter-E2 }
{ EParameter-E3 }
{ EParameter-E4 }
{ EParameter-E5 }
{ EParameter-E6 }
{ EParameter-E7 }
Monetary-Tariff-After-Valid-Units ::= < AVP Header: TBD >
{ EParameter-E1 }
{ EParameter-E2 }
{ EParameter-E3 }
{ EParameter-E4 }
{ EParameter-E5 }
{ EParameter-E6 }
{ EParameter-E7 }
Next-Monetary-Tariff ::= < AVP Header: TBD >
{ EParameter-E1 }
{ EParameter-E2 }
{ EParameter-E3 }
{ EParameter-E4 }
{ EParameter-E5 }
{ EParameter-E6 }
{ EParameter-E7 }
Extension ::= < AVP Header: TBD >
* [ AVP ]
Service-Rating ::= < AVP Header: TBD >
{ Service-Identifier }
* [ Destination-ID ]
[ Service-Information ]
[ Extension ]
[ Price ]
[ Billing-Info ]
[ Tariff-Switch-Time ]
{ Monetary-Tariff }
[ Next-Monetary-Tariff ]
[ Expiry-Time ]
[ Valid-Units ]
[ Monetary-Tariff-After-Valid-Units ]
* [ Counter ]
[ Basic-Price-Time-Stamp ]
[ Basic-Price ]
* [ Counter-Price ]
* [ Counter-Tariff ]
* [ Requested-Counter ]
[ Request-Sub-Type ]
[ Impact-On-Counter ]
[ Requested-Units ]
[ Consumed-Units ]
[ Consumed-Units-After-Tariff-Switch ]
[ Monetary-Quota ]
[ Minimal-Requested-Units ]
[ Allowed-Units ]
First-Request ::= < AVP Header: TBD > Enumerated (
SUBSEQUENT_REQUEST 0
FIRST_REQUEST 1
)
Request-Sub-Type ::= < AVP Header: TBD > Enumerated (
REQ_SUBTYPE_AOC 0
REQ_SUBTYPE_RESERVE 1
REQ_SUBTYPE_DEBIT 2
REQ_SUBTYPE_RELEASE 3
)
Destination-ID-Type ::= < AVP Header: TBD > Enumerated (
DESTINATION_NUMBER 0
DESTINATION_APN 1
DESTINATION_URL 2
DESTINATION_EMAILADDRESS 3
DESTINATION_PRIVATEID 4
)
Actual-Time ::= < AVP Header: TBD > Time
Allowed-Units ::= < AVP Header: TBD > Unsigned32
Basic-Price ::= < AVP Header: TBD > Unsigned32
Basic-Price-Time-Stamp ::= < AVP Header: TBD > Time
Begin-Time ::= < AVP Header: TBD > Time
Billing-Info ::= < AVP Header: TBD > UTF8String
Consumed-Units ::= < AVP Header: TBD > Unsigned32
Consumed-Units-After-Tariff-Switch ::= < AVP Header: TBD > Unsigned32
Counter-Change ::= < AVP Header: TBD > Integer32
Counter-Change-For-First-Chargeable-Time-Unit ::= < AVP Header: TBD > Integer32
Counter-Change-For-First-Chargeable-Time-Unit-After-Switch ::= < AVP Header: TBD > Integer32
Counter-Change-Per-Chargeable-Volume-Unit ::= < AVP Header: TBD > Integer32
Counter-Change-Per-Chargeable-Volume-Unit-After-Switch ::= < AVP Header: TBD > Integer32
Counter-Change-Per-Consumed-Service-Unit ::= < AVP Header: TBD > Integer32
Counter-Change-Per-Session ::= < AVP Header: TBD > Integer32
Counter-Change-Per-Subsequent-Chargeable-Time-Unit ::= < AVP Header: TBD > Integer32
Counter-Change-Per-Subsequent-Chargeable-Time-Unit-After-Switch ::= < AVP Header: TBD > Integer32
Counter-Expiry-Date ::= < AVP Header: TBD > Time
Counter-ID ::= < AVP Header: TBD > Unsigned32
Counter-Threshold ::= < AVP Header: TBD > Integer32
Counter-Type ::= < AVP Header: TBD > Unsigned32
Counter-Value ::= < AVP Header: TBD > Integer32
Counter-Value-Begin ::= < AVP Header: TBD > Integer32
Counter-Value-Change ::= < AVP Header: TBD > Integer32
Counter-Value-End ::= < AVP Header: TBD > Integer32
Destination-ID-Data ::= < AVP Header: TBD > UTF8String
EParameter-E1 ::= < AVP Header: TBD > Integer32
EParameter-E2 ::= < AVP Header: TBD > Integer32
EParameter-E3 ::= < AVP Header: TBD > Integer32
EParameter-E4 ::= < AVP Header: TBD > Integer32
EParameter-E5 ::= < AVP Header: TBD > Integer32
EParameter-E6 ::= < AVP Header: TBD > Integer32
EParameter-E7 ::= < AVP Header: TBD > Integer32
Expiry-Time ::= < AVP Header: TBD > Unsigned32
Minimal-Requested-Units ::= < AVP Header: TBD > Unsigned32
Monetary-Quota ::= < AVP Header: TBD > Unsigned32
Price ::= < AVP Header: TBD > Unsigned32
Requested-Counter ::= < AVP Header: TBD > Unsigned32
Requested-Units ::= < AVP Header: TBD > Unsigned32
Set-Counter-To ::= < AVP Header: TBD > Integer32
Tariff-Switch-Time ::= < AVP Header: TBD > Unsigned32
Valid-Units ::= < AVP Header: TBD > Unsigned32
Frens Jan Rumph
Sigh, what the $%^$% are standards for, if your not going to follow it? Sorry I just need to bitch a little about this. Grmbl…
I’m working on an implementation of the Ro reference point, for which I’m using a proprietary tool that converts definitions of Diameter applications (such as Credit Control or Diameter Base) in the ABNF like format defined in IETF RFC 3588 into Java Code. Which worked like a charm for the Diameter Base and Diameter Credit Control applications. I could just take the RFC text, strip off the ‘bla bla’ and make some minor adjustments in order for it to be able to be parsed, and voila: a Java class containing the entire spec… Quite nice
Now I’m trying to do the same for the 3GPP Ro reference point (as specified in 3GPP TS 32.299), pfff. And all of a sudden I noticed that some AVP names start with ‘3GPP’, which is not much of a problem at first sight, but… IETF has given this definition of a AVP name:
diameter-name = ALPHA *(ALPHA / DIGIT / "-")
Which clearly does not allow a command name or avp name to start with a DIGIT!!! So now I have to modify the converter in order to let it parse AVP’s like 3GPP-Charging-ID…
Sigh…
Update: But of course Java does not allow an identifier to start with a digit either!!! So ill just call them TGPP-* or something like that…
Again: Sigh…
Frens Jan Rumph