-// ANNA - Anna is Not Nothingness Anymore
-//
-// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
-//
-// http://redmine.teslayout.com/projects/anna-suite
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of the copyright holder nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Authors: eduardo.ramos.testillano@gmail.com
-// cisco.tierra@gmail.com
+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
// Local
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);
- std::string result = "";
- bool found = false;
- int pos = 1; // first avp
- const char * subscriptionIdPtr;
- const char * subscriptionIdDataPtr;
- int type;
- // Decoded avp information:
+ // Message datablock:
+ const char *avpsDB = db.getData() + Message::HeaderLength;
+ int avpsLen = db.getSize() - Message::HeaderLength;
+
+ // 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);
+ 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 "";
}
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);
- const char * serviceContextIdPtr = anna::diameter::codec::functions::findAVP(avpsDB, AVPID__Service_Context_Id);
+ //anna::DataBlock avpsDB(db.getData() + Message::HeaderLength, db.getSize() - Message::HeaderLength);
+ //const char * serviceContextIdPtr = anna::diameter::codec::functions::findAVP(avpsDB, AVPID__Service_Context_Id);
+
+ const char *avpsDB = db.getData() + Message::HeaderLength;
+ int avpsLen = db.getSize() - Message::HeaderLength;
+ const char * serviceContextIdPtr = anna::diameter::codec::functions::findAVP(avpsDB, avpsLen, AVPID__Service_Context_Id);
if(serviceContextIdPtr == NULL)
throw anna::RuntimeException("Service-Context-Id AVP not found in DataBlock provided", ANNA_FILE_LOCATION);