X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=source%2Fdiameter%2Fhelpers%2Fdcca%2Ffunctions.cpp;h=3e5f20a2385be5510b929de64fbe00b5f60673d6;hb=5a6cba5fde2b2f538a7515f8293cc0a8d9589dfa;hp=a630acd5087d9546483b213a389fd6db78903fa2;hpb=39033fd99e58e994a5e98c1060dcc79e0d81f9c9;p=anna.git diff --git a/source/diameter/helpers/dcca/functions.cpp b/source/diameter/helpers/dcca/functions.cpp index a630acd..3e5f20a 100644 --- a/source/diameter/helpers/dcca/functions.cpp +++ b/source/diameter/helpers/dcca/functions.cpp @@ -1,37 +1,9 @@ -// 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 @@ -63,53 +35,68 @@ const char anna::diameter::helpers::dcca::ChargingContextAndDomainSuffix::MMS[] // getters -std::string anna::diameter::helpers::dcca::functions::getSubscriptionIdData(const anna::DataBlock & db, int subscriptionIdType) throw(anna::RuntimeException) { +std::string anna::diameter::helpers::dcca::functions::getSubscriptionIdData(const anna::DataBlock & db, int subscriptionIdType) noexcept(false) { 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 ""; } -std::string anna::diameter::helpers::dcca::functions::getServiceContextId(const anna::DataBlock & db, ChargingContext::_v &chargingContext) throw(anna::RuntimeException) { +std::string anna::diameter::helpers::dcca::functions::getServiceContextId(const anna::DataBlock & db, ChargingContext::_v &chargingContext) noexcept(false) { 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);