Fix subscription-id decoding function
authorEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Tue, 1 Mar 2016 11:44:04 +0000 (12:44 +0100)
committerEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Tue, 1 Mar 2016 11:44:04 +0000 (12:44 +0100)
Subscription-Id-Type & Data are not fixed. Are manadatory. We need to fix the dictionary and the function behaviour.
This fix also the tinyTestcase.sh script for SLR/SNR issue

example/diameter/launcher/resources/scripts/tinyTestcase.sh
source/diameter/helpers/dcca/functions.cpp
source/diameter/stack/setups/avps_ietf.xml

index bd1c733..a8e44ea 100755 (executable)
@@ -115,7 +115,12 @@ update_testcase () {
   then
     # Send the request
     # Special case for SNR/SNA (code=8388636): the Session-Id is created on client and received on SLR previously
-    [ "$code" = "8388636" -a "$adml_type" = "server" ] && s_send="test|1|$send_command|$xml|$REQUEST_STEP"
+    if [ "$code" = "8388636" -a "$adml_type" = "server" ]
+    then
+      s_send="test|1|$send_command|$xml|$REQUEST_STEP"
+      s_wait="test|1|$wait_command|$code|0"
+    fi
+
     echo "$s_send" >> $TESTCASE_BN
 
     if [ -n "$resultcode" ]
@@ -139,7 +144,7 @@ update_testcase () {
 
     # Wait the request
     # Special case for SLR/SLA (code=8388635): the Session-Id is created on client
-    [ "$code" = "8388635" -a "$adml_type" = "server" ] && { s_wait="test|1|$wait_command|$code|1|||||$subscriber" ; REQUEST_STEP=$next_step_number ; }
+    [ "$code" = "8388635" -a "$adml_type" = "server" ] && { s_wait="test|1|$wait_command|$code|1" ; REQUEST_STEP=$next_step_number ; }
     echo "$s_wait" >> $TESTCASE_BN
 
     # Send the answer
index 89850a9..ccb1d80 100644 (file)
@@ -39,43 +39,51 @@ std::string anna::diameter::helpers::dcca::functions::getSubscriptionIdData(cons
   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 "";
 }
 
 
index 7a9e16d..f06ecd4 100644 (file)
    <avp name="Service-Parameter-Value" code="442" may-encrypt="yes" v-bit="mustnot" m-bit="may" p-bit="may"><single format-name="OctetString"/></avp>
    <avp name="Subscription-Id" code="443" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="may">
       <grouped>
-         <avprule id="Subscription-Id-Type" type="Fixed"/>
-         <avprule id="Subscription-Id-Data" type="Fixed"/>
+         <avprule id="Subscription-Id-Type" type="Mandatory"/>
+         <avprule id="Subscription-Id-Data" type="Mandatory"/>
       </grouped>
    </avp>
    <avp name="Subscription-Id-Data" code="444" may-encrypt="yes" v-bit="mustnot" m-bit="must" p-bit="may"><single format-name="UTF8String"/></avp>