1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
10 #include <anna/diameter/helpers/dcca/defines.hpp>
11 #include <anna/diameter/helpers/dcca/functions.hpp>
12 #include <anna/diameter/codec/Message.hpp>
13 #include <anna/diameter/codec/functions.hpp>
14 #include <anna/config/defines.hpp> // general types, decoding helpers (DECODE[2/3/4]BYTES_INDX_VALUETYPE), etc.
15 #include <anna/core/functions.hpp>
17 #include <anna/core/functions.hpp>
18 #include <anna/core/DataBlock.hpp>
24 using namespace anna::diameter::codec;
25 using namespace anna::diameter::helpers::dcca;
30 const char anna::diameter::helpers::dcca::ChargingContextAndDomainSuffix::Data[] = "32251@3gpp.org";
31 const char anna::diameter::helpers::dcca::ChargingContextAndDomainSuffix::Voice[] = "OCS-CS@telefonica.com";
32 const char anna::diameter::helpers::dcca::ChargingContextAndDomainSuffix::Content[] = "OCS-Generic-Services@telefonica.com";
33 const char anna::diameter::helpers::dcca::ChargingContextAndDomainSuffix::SMS[] = "32274@3gpp.org";
34 const char anna::diameter::helpers::dcca::ChargingContextAndDomainSuffix::MMS[] = "32270@3gpp.org";
38 std::string anna::diameter::helpers::dcca::functions::getSubscriptionIdData(const anna::DataBlock & db, int subscriptionIdType) throw(anna::RuntimeException) {
39 if(db.getSize() < Message::HeaderLength)
40 throw anna::RuntimeException("Not enough bytes to cover command header length", ANNA_FILE_LOCATION);
43 const char *avpsDB = db.getData() + Message::HeaderLength;
44 int avpsLen = db.getSize() - Message::HeaderLength;
46 // Auxiliar avp decoding:
51 std::string _dataG /* grouped avp */, _data1 /* first avp within grouped */, _data2 /* second avp within grouped */;
53 const char * subscriptionIdPtr;
54 int pos = 1; // first subscriber to find
55 while((subscriptionIdPtr = diameter::codec::functions::findAVP(avpsDB, avpsLen, AVPID__Subscription_Id, pos))) {
57 // Decode data for the grouped avp found:
58 diameter::codec::functions::decodeAVP(subscriptionIdPtr, _id, _flags, _length, _dataG);
59 // Data (_dataG) consists in two mandatory Avps in ANY order:
60 // - Subscription-Id-Type (Enumerated derived from Integer32)
61 // - Subscription-Id-Data (UTF8String)
63 // First AVP within _dataG:
64 diameter::codec::functions::decodeAVP(_dataG.c_str(), _id, _flags, _length, _data1);
66 if (_id == diameter::helpers::dcca::AVPID__Subscription_Id_Type) {
67 type = DECODE4BYTES_INDX_VALUETYPE(_data1, 0, int);
68 if (type == subscriptionIdType) {
69 diameter::codec::functions::decodeAVP(_dataG.c_str() + 12, _id, _flags, _length, _data2);
70 if (_id == diameter::helpers::dcca::AVPID__Subscription_Id_Data) return _data2;
73 else if (_id == diameter::helpers::dcca::AVPID__Subscription_Id_Data) {
74 diameter::codec::functions::decodeAVP(_dataG.c_str() + 20, _id, _flags, _length, _data2);
75 if (_id == diameter::helpers::dcca::AVPID__Subscription_Id_Type) {
76 type = DECODE4BYTES_INDX_VALUETYPE(_data2, 0, int);
77 if (type == subscriptionIdType) return _data1;
90 std::string anna::diameter::helpers::dcca::functions::getServiceContextId(const anna::DataBlock & db, ChargingContext::_v &chargingContext) throw(anna::RuntimeException) {
91 if(db.getSize() < Message::HeaderLength)
92 throw anna::RuntimeException("Not enough bytes to cover command header length", ANNA_FILE_LOCATION);
94 //anna::DataBlock avpsDB(db.getData() + Message::HeaderLength, db.getSize() - Message::HeaderLength);
95 //const char * serviceContextIdPtr = anna::diameter::codec::functions::findAVP(avpsDB, AVPID__Service_Context_Id);
97 const char *avpsDB = db.getData() + Message::HeaderLength;
98 int avpsLen = db.getSize() - Message::HeaderLength;
99 const char * serviceContextIdPtr = anna::diameter::codec::functions::findAVP(avpsDB, avpsLen, AVPID__Service_Context_Id);
101 if(serviceContextIdPtr == NULL)
102 throw anna::RuntimeException("Service-Context-Id AVP not found in DataBlock provided", ANNA_FILE_LOCATION);
104 // Decoded avp information:
109 anna::diameter::codec::functions::decodeAVP(serviceContextIdPtr, _id, _flags, _length, result /* data-part */);
110 // Charging context detection:
111 chargingContext = ChargingContext::Unknown;
113 if(anna::functions::endsWith(result, ChargingContextAndDomainSuffix::Data))
114 chargingContext = ChargingContext::Data;
115 else if(anna::functions::endsWith(result, ChargingContextAndDomainSuffix::Voice))
116 chargingContext = ChargingContext::Voice;
117 else if(anna::functions::endsWith(result, ChargingContextAndDomainSuffix::Content))
118 chargingContext = ChargingContext::Content;
119 else if(anna::functions::endsWith(result, ChargingContextAndDomainSuffix::SMS))
120 chargingContext = ChargingContext::SMS;
121 else if(anna::functions::endsWith(result, ChargingContextAndDomainSuffix::MMS))
122 chargingContext = ChargingContext::MMS;
125 // future kind of traffic