if(db.getSize() < Message::HeaderLength)
throw anna::RuntimeException("Not enough bytes to cover command header length", ANNA_FILE_LOCATION);
- //anna::DataBlock avpsDB(db.getData() + Message::HeaderLength, db.getSize() - Message::HeaderLength);
+ // Message datablock:
const char *avpsDB = db.getData() + Message::HeaderLength;
int avpsLen = db.getSize() - Message::HeaderLength;
- std::string result = "";
- bool found = false;
- int pos = 1; // first avp
- const char * subscriptionIdPtr;
- const char * subscriptionIdDataPtr;
- int type;
- // Decoded avp information:
+
+ // Auxiliar avp decoding:
AvpId _id;
char _flags;
int _length;
- std::string _dataG /* grouped */, _data;
-
- while(!found) {
- //subscriptionIdPtr = diameter::codec::functions::findAVP(avpsDB, AVPID__Subscription_Id, pos);
- subscriptionIdPtr = diameter::codec::functions::findAVP(avpsDB, avpsLen, AVPID__Subscription_Id, pos);
+ int type;
+ std::string _dataG /* grouped avp */, _data1 /* first avp within grouped */, _data2 /* second avp within grouped */;
- if(!subscriptionIdPtr) return result;
+ const char * subscriptionIdPtr;
+ int pos = 1; // first subscriber to find
+ while((subscriptionIdPtr = diameter::codec::functions::findAVP(avpsDB, avpsLen, AVPID__Subscription_Id, pos))) {
- // Look up type:
+ // Decode data for the grouped avp found:
diameter::codec::functions::decodeAVP(subscriptionIdPtr, _id, _flags, _length, _dataG);
- // Data is Fixed Subscription-Id-Type (Enumerated derived from Integer32) and then Fixed Subscription-Id-Data (UTF8String):
- // No need to find Subscription-Id-Type, it's always the first:
- diameter::codec::functions::decodeAVP(_dataG.c_str(), _id, _flags, _length, _data);
- // Enumerated:
- int type = DECODE4BYTES_INDX_VALUETYPE(_data, 0, int);
- found = (type == subscriptionIdType);
+ // Data (_dataG) consists in two mandatory Avps in ANY order:
+ // - Subscription-Id-Type (Enumerated derived from Integer32)
+ // - Subscription-Id-Data (UTF8String)
+
+ // First AVP within _dataG:
+ diameter::codec::functions::decodeAVP(_dataG.c_str(), _id, _flags, _length, _data1);
+
+ if (_id == diameter::helpers::dcca::AVPID__Subscription_Id_Type) {
+ type = DECODE4BYTES_INDX_VALUETYPE(_data1, 0, int);
+ if (type == subscriptionIdType) {
+ diameter::codec::functions::decodeAVP(_dataG.c_str() + 12, _id, _flags, _length, _data2);
+ if (_id == diameter::helpers::dcca::AVPID__Subscription_Id_Data) return _data2;
+ }
+ }
+ else if (_id == diameter::helpers::dcca::AVPID__Subscription_Id_Data) {
+ diameter::codec::functions::decodeAVP(_dataG.c_str() + 20, _id, _flags, _length, _data2);
+ if (_id == diameter::helpers::dcca::AVPID__Subscription_Id_Type) {
+ type = DECODE4BYTES_INDX_VALUETYPE(_data2, 0, int);
+ if (type == subscriptionIdType) return _data1;
+ }
+ }
+
pos++;
}
- // No need to find Subscription-Id-Data within _dataG, it's always the second, and the first takes always 3 words (no vendorID):
- subscriptionIdDataPtr = _dataG.c_str() + 12;
- diameter::codec::functions::decodeAVP(subscriptionIdDataPtr, _id, _flags, _length, result);
- // Result:
- return result;
+
+ // Nothing retrieved:
+ return "";
}