pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/36549?usp=email )


Change subject: asterisk: Introduce tests TC_internal_call_all_*registered
......................................................................

asterisk: Introduce tests TC_internal_call_all_*registered

Related: SYS#6782
Change-Id: Id06dedb3aac4f31f06281661391bf50640f6369a
---
M asterisk/Asterisk_Tests.ttcn
M asterisk/expected-results.xml
M library/SIP_Templates.ttcn
3 files changed, 232 insertions(+), 14 deletions(-)



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

diff --git a/asterisk/Asterisk_Tests.ttcn b/asterisk/Asterisk_Tests.ttcn
index 6ca05c1..93593ad 100644
--- a/asterisk/Asterisk_Tests.ttcn
+++ b/asterisk/Asterisk_Tests.ttcn
@@ -37,7 +37,9 @@
 } with { extension "internal" };
 private const charstring COORD_CMD_REGISTERED := "COORD_CMD_REGISTERED";
 private const charstring COORD_CMD_START := "COORD_CMD_START";
+private const charstring COORD_CMD_PICKUP := "COORD_CMD_PICKUP";
 private const charstring COORD_CMD_CALL_ESTABLISHED := 
"COORD_CMD_CALL_ESTABLISHED";
+private const charstring COORD_CMD_CALL_CANCELLED := 
"COORD_CMD_CALL_CANCELLED";
 private const charstring COORD_CMD_HANGUP := "COORD_CMD_HANGUP";

 type component test_CT {
@@ -54,6 +56,9 @@

        port Coord_PT COORD;
 }
+type record of ConnHdlr ConnHdlrList;
+
+const charstring broadcast_sip_extension := "0500";

 type record ConnHdlrPars {
        float t_guard,
@@ -70,6 +75,7 @@
        Contact local_contact,
        CallPars cp optional
 }
+type record of ConnHdlrPars ConnHdlrParsList;

 template (value) ConnHdlrPars t_Pars(charstring user,
                                     charstring display_name := "Anonymous",
@@ -103,11 +109,22 @@

 function f_init_ConnHdlrPars(integer idx := 1) runs on test_CT return 
ConnHdlrPars {
        var  template (value) CallPars cp := t_CallPars(idx := idx);
-       var template (value) ConnHdlrPars pars := t_Pars("0" & int2str(500 + 
idx),
+       var template (value) ConnHdlrPars pars := t_Pars("0" & 
int2str(str2int(broadcast_sip_extension) + idx),
                                                         cp := cp);
        return valueof(pars);
 }

+type record CallParsMT {
+       /* Whether to wait for COORD.receive(COORD_CMD_PICKUP) before accepting 
the call. */
+       boolean wait_coord_cmd_pickup,
+       /* Whether to expect CANCEL instead of ACK as answer to our OK */
+       boolean exp_cancel
+}
+private template (value) CallParsMT t_CallParsMT := {
+       wait_coord_cmd_pickup := false,
+       exp_cancel := false
+}
+
 type record CallPars {
        SipAddr calling optional,
        SipAddr called optional,
@@ -122,7 +139,8 @@
        charstring local_rtp_addr,
        uint16_t local_rtp_port,

-       SDP_Message peer_sdp optional
+       SDP_Message peer_sdp optional,
+       CallParsMT mt
 }

 private template (value) CallPars t_CallPars(integer idx := 1,
@@ -137,7 +155,8 @@
        sip_body := omit,
        local_rtp_addr := mp_local_sip_host,
        local_rtp_port := 1234 + 2*idx,
-       peer_sdp := omit
+       peer_sdp := omit,
+       mt := t_CallParsMT
 }

 function f_init() runs on test_CT {
@@ -444,8 +463,24 @@
        g_pars.cp.sip_seq_nr := g_pars.cp.sip_seq_nr + 1;
 }

+private function f_ConnHdlr_parse_initial_SIP_INVITE(PDU_SIP_Request 
rx_sip_req) runs on ConnHdlr
+{
+       f_SDP_decodeMessage(rx_sip_req.messageBody, g_pars.cp.peer_sdp);
+       log("Rx Initial MT INVITE decoded SDP: ", g_pars.cp.peer_sdp);
+
+       /* Obtain params: */
+       g_pars.cp.sip_call_id := rx_sip_req.msgHeader.callId.callid;
+       g_pars.cp.from_addr := 
valueof(ts_SipAddr_from_Addr_Union(rx_sip_req.msgHeader.fromField.addressField,
+                                                               
rx_sip_req.msgHeader.fromField.fromParams));
+       g_pars.cp.to_addr := 
valueof(ts_SipAddr_from_Addr_Union(rx_sip_req.msgHeader.toField.addressField,
+                                                               
rx_sip_req.msgHeader.toField.toParams));
+       g_pars.cp.to_addr.params := f_sip_param_set(g_pars.cp.to_addr.params, 
"tag", f_sip_rand_tag());
+       g_pars.cp.sip_seq_nr := rx_sip_req.msgHeader.cSeq.seqNumber;
+}
+
 /* Peer is calling us, accept it: */
-private altstep as_SIP_mt_call_accept(boolean exp_update_to_direct_rtp := 
true, boolean fail_others := true) runs on ConnHdlr
+private altstep as_SIP_mt_call_accept(boolean exp_update_to_direct_rtp := true,
+                                     boolean fail_others := true) runs on 
ConnHdlr
 {
        var template (present) PDU_SIP_Request exp_req :=
                tr_SIP_INVITE(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
@@ -461,17 +496,8 @@
                var Via via;
                var charstring tx_sdp;

-               f_SDP_decodeMessage(g_rx_sip_req.messageBody, 
g_pars.cp.peer_sdp);
-               log("Rx Initial MT INVITE decoded SDP: ", g_pars.cp.peer_sdp);
-
                /* Obtain params: */
-               g_pars.cp.sip_call_id := g_rx_sip_req.msgHeader.callId.callid;
-               g_pars.cp.from_addr := 
valueof(ts_SipAddr_from_Addr_Union(g_rx_sip_req.msgHeader.fromField.addressField,
-                                                                       
g_rx_sip_req.msgHeader.fromField.fromParams));
-               g_pars.cp.to_addr := 
valueof(ts_SipAddr_from_Addr_Union(g_rx_sip_req.msgHeader.toField.addressField,
-                                                                       
g_rx_sip_req.msgHeader.toField.toParams));
-               g_pars.cp.to_addr.params := 
f_sip_param_set(g_pars.cp.to_addr.params, "tag", f_sip_rand_tag());
-               g_pars.cp.sip_seq_nr := g_rx_sip_req.msgHeader.cSeq.seqNumber;
+               f_ConnHdlr_parse_initial_SIP_INVITE(g_rx_sip_req);
                via := g_rx_sip_req.msgHeader.via;


@@ -483,6 +509,10 @@
                                                g_pars.cp.sip_seq_nr);
                SIP.send(tx_resp);

+               if (g_pars.cp.mt.wait_coord_cmd_pickup) {
+                       COORD.receive(COORD_CMD_PICKUP);
+               }
+
                /* Tx 200 OK */
                tx_sdp := f_gen_sdp();
                tx_resp := ts_SIP_Response(g_pars.cp.sip_call_id,
@@ -515,6 +545,71 @@

 }

+/* Peer is calling us, but cancells it during ringing: */
+private altstep as_SIP_mt_call_cancelled(boolean fail_others := true) runs on 
ConnHdlr
+{
+       var template (present) PDU_SIP_Request exp_req :=
+               tr_SIP_INVITE(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
+                             ?,
+                             f_tr_From(g_pars.cp.calling),
+                             g_pars.cp.called,
+                             tr_Via_from(f_tr_HostPort(mp_remote_sip_host, 
mp_remote_sip_port)),
+                             ?, ?);
+       var charstring sip_expect_str := log2str(exp_req);
+
+       [] SIP.receive(exp_req) -> value g_rx_sip_req {
+               var template (value) PDU_SIP_Response tx_resp;
+               var Via via;
+               var template (present) SipAddr exp_to_addr;
+               var charstring tx_sdp;
+
+               /* Obtain params: */
+               f_ConnHdlr_parse_initial_SIP_INVITE(g_rx_sip_req);
+               via := g_rx_sip_req.msgHeader.via;
+
+
+               /* Tx 180 Ringing */
+               tx_resp := ts_SIP_Response_Ringing(g_pars.cp.sip_call_id,
+                                               g_pars.cp.from_addr,
+                                               g_pars.cp.to_addr,
+                                               via,
+                                               g_pars.cp.sip_seq_nr);
+               SIP.send(tx_resp);
+
+               if (g_pars.cp.mt.wait_coord_cmd_pickup) {
+                       COORD.receive(COORD_CMD_PICKUP);
+               }
+
+               /* Wait for CANCEL */
+               /* Cancel may come even before we send Ringing, hence To's "tag"
+                * may not be known by peer, so g_pars.to_addr can't be used 
here: */
+               exp_to_addr := 
ts_SipAddr_from_Addr_Union(g_rx_sip_req.msgHeader.toField.addressField,
+                                                         
g_rx_sip_req.msgHeader.toField.toParams);
+               exp_req := 
tr_SIP_CANCEL(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
+                                        g_pars.cp.sip_call_id,
+                                        g_pars.cp.from_addr,
+                                        exp_to_addr,
+                                        f_tr_Via_response(via),
+                                        g_pars.cp.sip_seq_nr, *);
+               as_SIP_expect_req(exp_req);
+
+               /* Tx 200 OK */
+               tx_sdp := f_gen_sdp();
+               tx_resp := ts_SIP_Response(g_pars.cp.sip_call_id,
+                                          g_pars.cp.from_addr,
+                                          g_pars.cp.to_addr,
+                                          "CANCEL", 200,
+                                          g_pars.cp.sip_seq_nr,
+                                          "OK",
+                                          via,
+                                          body := omit);
+               SIP.send(tx_resp);
+       }
+       [fail_others] as_SIP_fail_resp(sip_expect_str);
+       [fail_others] as_SIP_fail_req(sip_expect_str);
+
+}
+
 /* New INVITE arrives after MT call is established. Accept it: */
 private altstep as_SIP_exp_call_update(template (present) integer exp_seq_nr 
:= ?, boolean fail_others := true) runs on ConnHdlr
 {
@@ -681,6 +776,13 @@
        f_SIP_register();
        COORD.send(COORD_CMD_REGISTERED);

+       if (g_pars.cp.mt.exp_cancel) {
+               as_SIP_mt_call_cancelled();
+               COORD.send(COORD_CMD_CALL_CANCELLED);
+               setverdict(pass);
+               return;
+       }
+
        as_SIP_mt_call_accept();
        COORD.send(COORD_CMD_CALL_ESTABLISHED);

@@ -720,6 +822,9 @@
        [] COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn[1];
        }

+       /* Call on-going */
+       f_sleep(1.0);
+
        COORD.send(COORD_CMD_HANGUP) to vc_conn[0];


@@ -727,6 +832,87 @@
        vc_conn[1].done;
 }

+/* One of the users calls (INVITE) shared extension, which makes all other user
+ * equipments ring (INVITE). The first one to pick up the call (OK 200) gets 
the
+ * call established (ACK), others get a CANCEL event. */
+private function TC_internal_call_all_Nregistered(integer num_conns := 2) runs 
on test_CT {
+       //var ConnHdlrParsList pars := {};
+       var ConnHdlrList vc_conn_list := {};
+       const integer vc_conn_mo_idx := 0; /* Index of MO leg in vc_conn_list */
+       const integer vc_conn_mt_idx := 1; /* Index of MT leg in vc_conn_list, 
peer picking up first the call */
+       var SipAddr broadcast_sip_record;
+       var ConnHdlrPars pars_mo;
+
+       f_init();
+
+       broadcast_sip_record := 
valueof(ts_SipAddr(ts_HostPort(mp_local_sip_host),
+                                       ts_UserInfo(broadcast_sip_extension)));
+
+       for (var integer i := 0; i < num_conns; i := i + 1) {
+               var ConnHdlrPars pars;
+               var ConnHdlr vc_conn;
+               pars := f_init_ConnHdlrPars(idx := i + 1);
+               if (i == vc_conn_mo_idx) { /* MO */
+                       pars.cp.calling := pars.registrar_sip_record;
+                       pars.cp.called := broadcast_sip_record;
+                       vc_conn := 
f_start_handler(refers(f_TC_internal_call_mo), pars);
+                       pars_mo := pars;
+               } else { /* MT */
+                       pars.cp.calling := pars_mo.registrar_sip_record;
+                       pars.cp.called := pars.local_sip_record;
+                       pars.cp.mt.wait_coord_cmd_pickup := true;
+                       if (i != vc_conn_mt_idx) {
+                               /* Only first MT picking up (OK 200 INVITE) 
will be ACKed, others CANCELed: */
+                               pars.cp.mt.exp_cancel := true;
+                       }
+                       vc_conn := 
f_start_handler(refers(f_TC_internal_call_mt), pars);
+               }
+               vc_conn_list := vc_conn_list & { vc_conn };
+       }
+
+       /* Wait all users are registered: */
+       for (var integer i := 0; i < num_conns; i := i + 1) {
+               /* Note: "from vc_conn_list[i]" can't be used since they may 
arrive from components in any order: */
+               COORD.receive(COORD_CMD_REGISTERED);
+       }
+
+       /* Ask MO user to start the call: */
+       COORD.send(COORD_CMD_START) to vc_conn_list[vc_conn_mo_idx];
+
+       /* Make sure the desired MT is the one picking up first the call: */
+       COORD.send(COORD_CMD_PICKUP) to vc_conn_list[vc_conn_mt_idx];
+       interleave {
+       [] COORD.receive(COORD_CMD_CALL_ESTABLISHED) from 
vc_conn_list[vc_conn_mo_idx];
+       [] COORD.receive(COORD_CMD_CALL_ESTABLISHED) from 
vc_conn_list[vc_conn_mt_idx];
+       }
+
+       /* Pick up from other phone calls and expect CANCEL: */
+       for (var integer i := 0; i < num_conns; i := i + 1) {
+               if (i != vc_conn_mo_idx and i != vc_conn_mt_idx) {
+                       COORD.send(COORD_CMD_PICKUP) to vc_conn_list[i];
+                       COORD.receive(COORD_CMD_CALL_CANCELLED) from 
vc_conn_list[i];
+               }
+       }
+
+       /* Call on-going */
+       f_sleep(1.0);
+
+       COORD.send(COORD_CMD_HANGUP) to vc_conn_list[vc_conn_mo_idx];
+
+       for (var integer i := 0; i < num_conns; i := i + 1) {
+               vc_conn_list[i].done;
+       }
+}
+testcase TC_internal_call_all_2registered() runs on test_CT {
+       TC_internal_call_all_Nregistered(2);
+}
+testcase TC_internal_call_all_3registered() runs on test_CT {
+       TC_internal_call_all_Nregistered(3);
+}
+testcase TC_internal_call_all_4registered() runs on test_CT {
+       TC_internal_call_all_Nregistered(4);
+}
+
 testcase TC_selftest() runs on test_CT {
        f_sip_digest_selftest();
        setverdict(pass);
@@ -735,6 +921,9 @@
 control {
        execute( TC_internal_registration() );
        execute( TC_internal_call_momt() );
+       execute( TC_internal_call_all_2registered() );
+       execute( TC_internal_call_all_3registered() );
+       execute( TC_internal_call_all_4registered() );
 }

 }
diff --git a/asterisk/expected-results.xml b/asterisk/expected-results.xml
index 3eb9c8f..745a4d7 100644
--- a/asterisk/expected-results.xml
+++ b/asterisk/expected-results.xml
@@ -2,4 +2,7 @@
 <testsuite name='Titan' tests='9' failures='0' errors='0' skipped='0' 
inconc='0' time='MASKED'>
   <testcase classname='Asterisk_Tests' name='TC_internal_registration' 
time='MASKED'/>
   <testcase classname='Asterisk_Tests' name='TC_internal_call_momt' 
time='MASKED'/>
+    <testcase classname='Asterisk_Tests' 
name='TC_internal_call_all_2registered' time='MASKED'/>
+    <testcase classname='Asterisk_Tests' 
name='TC_internal_call_all_3registered' time='MASKED'/>
+    <testcase classname='Asterisk_Tests' 
name='TC_internal_call_all_4registered' time='MASKED'/>
 </testsuite>
diff --git a/library/SIP_Templates.ttcn b/library/SIP_Templates.ttcn
index 9a9b44c..be07196 100644
--- a/library/SIP_Templates.ttcn
+++ b/library/SIP_Templates.ttcn
@@ -677,6 +677,22 @@
        payload := omit
 }

+template (present) PDU_SIP_Request
+tr_SIP_CANCEL(template (present) SipUrl uri,
+             template (present) CallidString call_id,
+             template (present) SipAddr from_addr,
+             template (present) SipAddr to_addr,
+             template (present) Via via,
+             template (present) integer seq_nr,
+             template charstring body := *) := {
+       requestLine := tr_SIP_ReqLine(CANCEL_E, uri),
+       msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, *,
+                                    via,
+                                    "CANCEL", *, seq_nr),
+       messageBody := body,
+       payload := omit
+}
+
 template (value) PDU_SIP_Response
 ts_SIP_Response(template (value) CallidString call_id,
                template (value) SipAddr from_addr,

--
To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/36549?usp=email
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: Id06dedb3aac4f31f06281661391bf50640f6369a
Gerrit-Change-Number: 36549
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pes...@sysmocom.de>
Gerrit-MessageType: newchange

Reply via email to