Remove dynamic exceptions
[anna.git] / source / diameter / helpers / dcca / functions.cpp
index fc7f295..3e5f20a 100644 (file)
@@ -1,37 +1,9 @@
-// ANNA - Anna is Not Nothingness Anymore
-//
-// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
-//
-// https://bitbucket.org/testillano/anna
-//
-// 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 Google Inc. 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);