pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/28172 )


Change subject: ggsn: Validate charging reported values
......................................................................

ggsn: Validate charging reported values

Change-Id: I497309bb0b30c61bdb00e0c08f18294ecd4dd485
---
M ggsn_tests/GGSN_Tests.ttcn
M library/DIAMETER_Emulation.ttcn
M library/DIAMETER_Templates.ttcn
3 files changed, 122 insertions(+), 30 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks 
refs/changes/72/28172/1

diff --git a/ggsn_tests/GGSN_Tests.ttcn b/ggsn_tests/GGSN_Tests.ttcn
index 4a5f0ba..dffe0bf 100644
--- a/ggsn_tests/GGSN_Tests.ttcn
+++ b/ggsn_tests/GGSN_Tests.ttcn
@@ -652,8 +652,8 @@
                return tpl;
        }

-       private altstep as_DIA_Gy_CCR(template (omit) PdpContext ctx, 
DCC_NONE_CC_Request_Type req_type) runs on GT_CT {
-               var PDU_DIAMETER rx_dia;
+       private altstep as_DIA_Gy_CCR(template (omit) PdpContext ctx, 
DCC_NONE_CC_Request_Type req_type,
+                                     out PDU_DIAMETER rx_dia) runs on GT_CT {
                [] Gy_UNIT.receive(f_tr_DIA_Gy_CCR(ctx, req_type := req_type)) 
-> value rx_dia {
                        var template (value) PDU_DIAMETER tx_dia;
                        var template (omit) AVP avp;
@@ -685,6 +685,7 @@
                var Gtp1cUnitdata ud;
                var CreatePDPContextResponse cpr;
                var default d;
+               var PDU_DIAMETER rx_dia;

                log("sending CreatePDP");
                f_send_gtpc(ts_GTPC_CreatePDP(g_peer_c, g_c_seq_nr, ctx.imsi, 
g_restart_ctr,
@@ -697,7 +698,7 @@
                        as_DIA_Gx_CCR(INITIAL_REQUEST);
                }
                if (Gy_PROC.checkstate("Connected")) {
-                       as_DIA_Gy_CCR(ctx, INITIAL_REQUEST);
+                       as_DIA_Gy_CCR(ctx, INITIAL_REQUEST, rx_dia);
                }
                alt {
                        [] GTPC.receive(tr_GTPC_MsgType(g_peer_c, 
createPDPContextResponse, ctx.teic)) -> value ud {
@@ -742,7 +743,7 @@
                T_default.stop;
        }

-       function f_pdp_ctx_del(PdpContext ctx, template BIT1 teardown_ind, OCT1 
expect_causevalue := '80'O, boolean expect_diameter := true) runs on GT_CT {
+       function f_pdp_ctx_del_out(PdpContext ctx, out PDU_DIAMETER rx_dia, 
template BIT1 teardown_ind, OCT1 expect_causevalue := '80'O, boolean 
expect_diameter := true) runs on GT_CT {
                var Gtp1cUnitdata ud;
                var default d;
                var OCT4 expect_teid;
@@ -762,7 +763,7 @@
                        as_DIA_Gx_CCR(TERMINATION_REQUEST);
                }
                if (Gy_PROC.checkstate("Connected") and expect_diameter) {
-                       as_DIA_Gy_CCR(ctx, TERMINATION_REQUEST);
+                       as_DIA_Gy_CCR(ctx, TERMINATION_REQUEST, rx_dia);
                }
                alt {
                        [] GTPC.receive(tr_GTPC_MsgType(g_peer_c, 
deletePDPContextResponse, expect_teid)) -> value ud {
@@ -777,6 +778,10 @@
                deactivate(d);
                T_default.stop;
        }
+       function f_pdp_ctx_del(PdpContext ctx, template BIT1 teardown_ind, OCT1 
expect_causevalue := '80'O, boolean expect_diameter := true) runs on GT_CT {
+               var PDU_DIAMETER rx_dia;
+               f_pdp_ctx_del_out(ctx, rx_dia, teardown_ind, expect_causevalue, 
expect_diameter)
+       }

        /* send a Update PdP Context Request, expect Response */
        function f_pdp_ctx_update(inout PdpContext ctx, OCT1 exp_cause := 
'80'O, template (omit) OCT4 new_teid := omit, template (omit) OCT4 new_teic := 
omit) runs on GT_CT {
@@ -2168,6 +2173,7 @@
                var OCT4 saddr;
                var integer teic;
                var integer idx;
+               var PDU_DIAMETER rx_dia;

                f_init();

@@ -2183,7 +2189,7 @@
                T_next.start;
                alt {
                [Gx_PROC.checkstate("Connected")] 
as_DIA_Gx_CCR(INITIAL_REQUEST) { repeat; }
-               [Gy_PROC.checkstate("Connected")] as_DIA_Gy_CCR(omit, 
INITIAL_REQUEST) { repeat; }
+               [Gy_PROC.checkstate("Connected")] as_DIA_Gy_CCR(omit, 
INITIAL_REQUEST, rx_dia) { repeat; }
                [] pingpong();
                [] T_next.timeout {
                        f_send_gtpc(ts_GTPC_CreatePDP(g_peer_c, g_c_seq_nr, 
ctx[next_req_ctx].imsi, g_restart_ctr,
@@ -2239,7 +2245,7 @@
                T_next.start;
                alt {
                [Gx_PROC.checkstate("Connected")] 
as_DIA_Gx_CCR(TERMINATION_REQUEST) { repeat; }
-               [Gy_PROC.checkstate("Connected")] as_DIA_Gy_CCR(omit, 
TERMINATION_REQUEST) { repeat; }
+               [Gy_PROC.checkstate("Connected")] as_DIA_Gy_CCR(omit, 
TERMINATION_REQUEST, rx_dia) { repeat; }
                [] pingpong();
                [] T_next.timeout {
                        f_send_gtpc(ts_GTPC_DeletePDP(g_peer_c, g_c_seq_nr, 
ctx[next_req_ctx].teic_remote, ctx[next_req_ctx].nsapi, '1'B));
@@ -2284,6 +2290,7 @@
                var CreatePDPContextResponse cpr;
                var TEIClist teic_list := {};
                var integer teic;
+               var PDU_DIAMETER rx_dia;

                f_init();

@@ -2292,7 +2299,7 @@
                T_next.start;
                alt {
                [Gx_PROC.checkstate("Connected")] 
as_DIA_Gx_CCR(INITIAL_REQUEST) { repeat; }
-               [Gy_PROC.checkstate("Connected")] as_DIA_Gy_CCR(omit, 
INITIAL_REQUEST) { repeat; }
+               [Gy_PROC.checkstate("Connected")] as_DIA_Gy_CCR(omit, 
INITIAL_REQUEST, rx_dia) { repeat; }
                [] pingpong();
                [] T_next.timeout {
                        if (cont_req) {
@@ -2343,7 +2350,7 @@
                T_next.start;
                alt {
                [Gx_PROC.checkstate("Connected")] 
as_DIA_Gx_CCR(TERMINATION_REQUEST) { repeat; }
-               [Gy_PROC.checkstate("Connected")] as_DIA_Gy_CCR(omit, 
TERMINATION_REQUEST) { repeat; }
+               [Gy_PROC.checkstate("Connected")] as_DIA_Gy_CCR(omit, 
TERMINATION_REQUEST, rx_dia) { repeat; }
                [] pingpong();
                [] T_next.timeout {
                        f_send_gtpc(ts_GTPC_DeletePDP(g_peer_c, g_c_seq_nr, 
teic_list[next_req_ctx], '0001'B, '1'B));
@@ -2374,9 +2381,50 @@
                f_shutdown_helper();
        }

+       private function f_validate_gy_cc_report(PDU_DIAMETER rx_dia, template 
(present) DCA_3GPP_Reporting_Reason repreason_exp := ?,
+                                             template (present) integer 
cc_time_exp := ?,
+                                             template (present) integer 
cc_in_oct_exp := ?,
+                                             template (present) integer 
cc_out_oct_exp := ?)
+       {
+               var AVP multi_services_cc, used_service_unit;
+               var AVP_Grouped multi_services_cc_data, used_service_unit_data;
+               var AVP repreason, cc_time, cc_in_oct, cc_out_oct;
+
+               multi_services_cc := f_DIAMETER_get_avp_or_fail(rx_dia, 
c_AVP_Code_DCC_NONE_Multiple_Services_Credit_Control);
+               multi_services_cc_data := 
valueof(multi_services_cc.avp_data.avp_DCC_NONE_Multiple_Services_Credit_Control);
+
+               repreason := 
f_AVP_Grouped_get_avp_or_fail(multi_services_cc_data, 
c_AVP_Code_DCA_3GPP_Reporting_Reason);
+               if (not match(repreason.avp_data.avp_DCA_3GPP_Reporting_Reason, 
repreason_exp)) {
+                       Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+                               log2str("3GPP-Reporting-Reason mismatch ", 
repreason, " vs exp ", repreason_exp));
+               }
+
+               used_service_unit := 
f_AVP_Grouped_get_avp_or_fail(multi_services_cc_data, 
c_AVP_Code_DCC_NONE_Used_Service_Unit);
+               used_service_unit_data := 
valueof(used_service_unit.avp_data.avp_DCC_NONE_Used_Service_Unit);
+
+               cc_time := 
f_AVP_Grouped_get_avp_or_fail(used_service_unit_data, 
c_AVP_Code_DCC_NONE_CC_Time);
+               if (not match(oct2int(cc_time.avp_data.avp_DCC_NONE_CC_Time), 
cc_time_exp)) {
+                       Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+                               log2str("3GPP-CC-Time mismatch ", cc_time, " vs 
exp ", cc_time_exp));
+               }
+
+               cc_in_oct := 
f_AVP_Grouped_get_avp_or_fail(used_service_unit_data, 
c_AVP_Code_DCC_NONE_CC_Input_Octets);
+               if (not 
match(oct2int(cc_in_oct.avp_data.avp_DCC_NONE_CC_Input_Octets), cc_in_oct_exp)) 
{
+                       Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+                               log2str("3GPP-CC-Input-Octets mismatch ", 
cc_in_oct, " vs exp ", cc_in_oct_exp));
+               }
+
+               cc_out_oct := 
f_AVP_Grouped_get_avp_or_fail(used_service_unit_data, 
c_AVP_Code_DCC_NONE_CC_Output_Octets);
+               if (not 
match(oct2int(cc_out_oct.avp_data.avp_DCC_NONE_CC_Output_Octets), 
cc_out_oct_exp)) {
+                       Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+                               log2str("3GPP-CC-Output-Octets mismatch ", 
cc_out_oct, " vs exp ", cc_out_oct_exp));
+               }
+       }
+
        /* Test charging over Gy interface. */
        testcase TC_gy_charging_cc_time() runs on GT_CT {
                var default d;
+               var PDU_DIAMETER rx_dia;

                g_gy_validity_time := 3; /* Grant access for 3 seconds, needs 
to be re-validated afterwards */
                f_init();
@@ -2396,17 +2444,20 @@

                g_gy_validity_time := 2;
                /* First update reports octests/pkt on both UL/DL (see icmp 
ping-pong above) */
-               as_DIA_Gy_CCR(ctx, UPDATE_REQUEST);
+               as_DIA_Gy_CCR(ctx, UPDATE_REQUEST, rx_dia);
+               f_validate_gy_cc_report(rx_dia, VALIDITY_TIME, (3..4), 28, 28);

                /* Second update: 0 ul/dl pkt/octet should be reported, since 
nothing was sent */
-               as_DIA_Gy_CCR(ctx, UPDATE_REQUEST);
+               as_DIA_Gy_CCR(ctx, UPDATE_REQUEST, rx_dia);
+               f_validate_gy_cc_report(rx_dia, VALIDITY_TIME, (2..3), 0, 0);

                /* Third update: make sure report contains again octets/pkts 
for both UL/DL: */
                f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr, dns1_addr));
                f_wait_icmp4_echo_reply(ctx);
                f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr, dns1_addr));
                f_wait_icmp4_echo_reply(ctx);
-               as_DIA_Gy_CCR(ctx, UPDATE_REQUEST);
+               as_DIA_Gy_CCR(ctx, UPDATE_REQUEST, rx_dia);
+               f_validate_gy_cc_report(rx_dia, VALIDITY_TIME, (2..3), 56, 56);

                /* Let the CCA reach the GGSN */
                f_sleep(0.5);
@@ -2418,7 +2469,8 @@
                f_send_gtpu(ctx, f_gen_icmpv4_echo(saddr, dns1_addr));
                f_wait_icmp4_echo_reply(ctx);

-               f_pdp_ctx_del(ctx, '1'B);
+               f_pdp_ctx_del_out(ctx, rx_dia, '1'B);
+               f_validate_gy_cc_report(rx_dia, FINAL, (0..2), 28, 28);


                f_shutdown_helper();
diff --git a/library/DIAMETER_Emulation.ttcn b/library/DIAMETER_Emulation.ttcn
index 748b452..09f92be 100644
--- a/library/DIAMETER_Emulation.ttcn
+++ b/library/DIAMETER_Emulation.ttcn
@@ -211,23 +211,6 @@
        }
 }

-function f_DIAMETER_get_avp(PDU_DIAMETER pdu, template (present) AVP_Code 
avp_code)
-return template (omit) AVP
-{
-       var integer i;
-
-       for (i := 0; i < lengthof(pdu.avps); i := i+1) {
-               if (not ispresent(pdu.avps[i].avp)) {
-                       continue;
-               }
-               var AVP_Header hdr := pdu.avps[i].avp.avp_header;
-               if (match(hdr.avp_code, avp_code)) {
-                       return pdu.avps[i].avp;
-               }
-       }
-       return omit;
-}
-
 function f_DIAMETER_get_imsi(PDU_DIAMETER pdu) return template (omit) IMSI
 {
        var template (omit) AVP imsi_avp;
diff --git a/library/DIAMETER_Templates.ttcn b/library/DIAMETER_Templates.ttcn
index 855358d..38c44e8 100644
--- a/library/DIAMETER_Templates.ttcn
+++ b/library/DIAMETER_Templates.ttcn
@@ -11,6 +11,7 @@

 import from DIAMETER_Types all;
 import from Osmocom_Types all;
+import from Misc_Helpers all;

 /* 
https://www.iana.org/assignments/aaa-parameters/aaa-parameters.xhtml#aaa-parameters-4
 */
 type enumerated DIAMETER_Resultcode {
@@ -1611,4 +1612,60 @@
                        tr_AVP_OriginStateId(state_id)
        ));

+function f_DIAMETER_get_avp(PDU_DIAMETER pdu, template (present) AVP_Code 
avp_code)
+return template (omit) AVP
+{
+       var integer i;
+
+       for (i := 0; i < lengthof(pdu.avps); i := i+1) {
+               if (not ispresent(pdu.avps[i].avp)) {
+                       continue;
+               }
+               var AVP_Header hdr := pdu.avps[i].avp.avp_header;
+               if (match(hdr.avp_code, avp_code)) {
+                       return pdu.avps[i].avp;
+               }
+       }
+       return omit;
+}
+function f_DIAMETER_get_avp_or_fail(PDU_DIAMETER pdu, template (present) 
AVP_Code avp_code)
+return AVP
+{
+       var template (omit) AVP avp;
+       avp := f_DIAMETER_get_avp(pdu, avp_code);
+       if (istemplatekind(avp, "omit")) {
+               Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+                       log2str("AVP ", avp_code, " not found in ", pdu));
+       }
+       return valueof(avp);
+}
+
+function f_AVP_Grouped_get_avp(AVP_Grouped avp_grp, template (present) 
AVP_Code avp_code)
+return template (omit) AVP
+{
+       var integer i;
+
+       for (i := 0; i < lengthof(avp_grp); i := i+1) {
+               if (not ispresent(avp_grp[i].avp)) {
+                       continue;
+               }
+               var AVP_Header hdr := avp_grp[i].avp.avp_header;
+               if (match(hdr.avp_code, avp_code)) {
+                       return avp_grp[i].avp;
+               }
+       }
+       return omit;
+}
+function f_AVP_Grouped_get_avp_or_fail(AVP_Grouped avp_grp, template (present) 
AVP_Code avp_code)
+return AVP
+{
+       var template (omit) AVP avp;
+       avp := f_AVP_Grouped_get_avp(avp_grp, avp_code);
+       if (istemplatekind(avp, "omit")) {
+               Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+                       log2str("AVP ", avp_code, " not found in ", avp_grp));
+       }
+       return valueof(avp);
+}
+
 }

--
To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/28172
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: I497309bb0b30c61bdb00e0c08f18294ecd4dd485
Gerrit-Change-Number: 28172
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>
Gerrit-MessageType: newchange

Reply via email to