Review at  https://gerrit.osmocom.org/6886

bts: Add paging related tests

We're testing at 80% and 200% of PCH capacity, both for either IMSI-only
or TMSI-only paging requests.  The way how we test ensures:

* the expected number of paged mobile identities end up on the Um interface
* we implicitly check the queuing limit of 200 paging records by
  overflowing it in the 20-seconds-of-200%-load cases
* we implicitly check the batching of mobile identities into different
  paging types
* we test the PCH load reporting over RSL

As a side note, in case you were ever wondering what's the expected
paging throughput / capacity, there are now helper functions to compute
it.  For our combined CCCH/SDCCH4, it's about 16 IMSIs per second or
about 32 TMSIs per second.

Change-Id: I0b80b72bdab3d80d915296d70e1174623fbd8610
---
A bts/BTS_Tests.default
M bts/BTS_Tests.ttcn
M library/GSM_Types.ttcn
M library/L1CTL_Types.ttcn
M library/L3_Templates.ttcn
M library/RSL_Types.ttcn
6 files changed, 511 insertions(+), 12 deletions(-)


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

diff --git a/bts/BTS_Tests.default b/bts/BTS_Tests.default
new file mode 100644
index 0000000..927d7c4
--- /dev/null
+++ b/bts/BTS_Tests.default
@@ -0,0 +1,21 @@
+[LOGGING]
+"BTS-Test-RSL-IPA".FileMask := ERROR | WARNING;
+"BTS-Test-RSL".FileMask := ERROR | WARNING;
+"IPA0-CTRL-IPA".FileMask := ERROR | WARNING;
+mtc.FileMask := LOG_ALL | TTCN_DEBUG | TTCN_MATCHING | DEBUG_ENCDEC;
+
+[TESTPORT_PARAMETERS]
+*.BTSVTY.CTRL_MODE := "client"
+*.BTSVTY.CTRL_HOSTNAME := "127.0.0.1"
+*.BTSVTY.CTRL_PORTNUM := "4241"
+*.BTSVTY.CTRL_LOGIN_SKIPPED := "yes"
+*.BTSVTY.CTRL_DETECT_SERVER_DISCONNECTED := "yes"
+*.BTSVTY.CTRL_READMODE := "buffered"
+*.BTSVTY.CTRL_CLIENT_CLEANUP_LINEFEED := "yes"
+*.BTSVTY.PROMPT1 := "OsmoBTS> "
+
+[MODULE_PARAMETERS]
+//Osmocom_VTY_Functions.mp_prompt_prefix := "OsmoBTS";
+
+[EXECUTE]
+BTS_Tests.control
diff --git a/bts/BTS_Tests.ttcn b/bts/BTS_Tests.ttcn
index 3bf412e..1548908 100644
--- a/bts/BTS_Tests.ttcn
+++ b/bts/BTS_Tests.ttcn
@@ -20,8 +20,10 @@
 import from TRXC_CodecPort all;
 import from TRXC_CodecPort_CtrlFunct all;
 
-import from L3_Templates all;
 import from MobileL3_CommonIE_Types all;
+import from MobileL3_RRM_Types all;
+import from MobileL3_Types all;
+import from L3_Templates all;
 
 /* The tests assume a BTS with the following timeslot configuration:
  * TS0 : Combined CCCH + SDCCH/4
@@ -39,10 +41,15 @@
 }
 
 type component test_CT extends CTRL_Adapter_CT {
+       /* IPA Emulation component underneath RSL */
        var IPA_Emulation_CT vc_IPA;
-
+       /* RSL Emulation component (for ConnHdlr tests) */
        var RSL_Emulation_CT vc_RSL;
+       /* Direct RSL_CCHAN_PT */
        port RSL_CCHAN_PT RSL_CCHAN;
+
+       /* L1CTL port (for classic tests) */
+       port L1CTL_PT L1CTL;
 }
 
 /* an individual call / channel */
@@ -125,7 +132,7 @@
 }
 
 /* global init function */
-function f_init(charstring id) runs on test_CT {
+function f_init(charstring id := "BTS-Test") runs on test_CT {
        f_init_rsl(id);
        RSL_CCHAN.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP});
 
@@ -134,6 +141,12 @@
        log("Sending SI3 ", si3);
        var octetstring si3_enc := enc_GsmRrMessage(si3);
        RSL_CCHAN.send(ts_RSL(ts_RSL_BCCH_INFO(RSL_SYSTEM_INFO_3, si3_enc)));
+}
+
+/* Attach L1CTL to master test_CT (classic tests, non-handler mode) */
+function f_init_l1ctl() runs on test_CT {
+       map(self:L1CTL, system:L1CTL);
+       f_connect_reset(L1CTL);
 }
 
 type function void_fn(charstring id) runs on ConnHdlr;
@@ -160,10 +173,7 @@
        }
 }
 
-private function f_l1_tune() runs on ConnHdlr {
-       /* tune our virtual L1 to the right ARFCN */
-       //var BCCH_tune_req tune_req := { arfcn := { false, mp_trx0_arfcn }, 
combined_ccch := true };
-       //L1.send(tune_req);
+private function f_l1_tune(L1CTL_PT L1CTL) {
        f_L1CTL_FBSB(L1CTL, { false, mp_trx0_arfcn }, CCCH_MODE_COMBINED);
 }
 
@@ -368,7 +378,7 @@
 }
 
 function f_TC_chan_req(charstring id) runs on ConnHdlr {
-       f_l1_tune();
+       f_l1_tune(L1CTL);
 
        RSL.clear;
        //L1.send(DCCH_establish_req:{ra := 23});
@@ -547,7 +557,7 @@
 
 /* establish DChan, verify existance + contents of measurement reports */
 function f_TC_meas_res_periodic(charstring id) runs on ConnHdlr {
-       f_l1_tune();
+       f_l1_tune(L1CTL);
        RSL.clear;
 
        g_pars.l1_pars.meas_ul.full.rxlev := dbm2rxlev(-100);
@@ -622,7 +632,7 @@
 
 /* Test if a channel without valid uplink bursts generates RSL CONN FAIL IND */
 private function f_TC_conn_fail_crit(charstring id) runs on ConnHdlr {
-       f_l1_tune();
+       f_l1_tune(L1CTL);
        RSL.clear;
 
        f_est_dchan();
@@ -652,8 +662,326 @@
        vc_conn.done;
 }
 
+import from IPA_Types all;
+template ASP_RSL_Unitdata ts_RSL(template RSL_Message rsl, IpaStreamId sid := 
IPAC_PROTO_RSL_TRX0) := {
+       streamId := sid,
+       rsl := rsl
+}
+template ASP_RSL_Unitdata tr_RSL(template RSL_Message rsl,
+                                template IpaStreamId sid := 
IPAC_PROTO_RSL_TRX0) := {
+       streamId := sid,
+       rsl := rsl
+}
+
+function tmsi_is_dummy(TMSIP_TMSI_V tmsi) return boolean {
+       if (tmsi == 'FFFFFFFF'O) {
+               return true;
+       } else {
+               return false;
+       }
+}
 
 
+altstep as_l1_count_paging(inout integer num_paging_rcv_msgs, inout integer 
num_paging_rcv_ids)
+runs on test_CT {
+       var L1ctlDlMessage dl;
+       [] L1CTL.receive(t_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0), ?, 
c_DummyUI)) {
+               repeat;
+       }
+       [] L1CTL.receive(t_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0))) -> value dl 
{
+               var octetstring without_plen :=
+                       substr(dl.payload.data_ind.payload, 1, 
lengthof(dl.payload.data_ind.payload)-1);
+               var PDU_ML3_NW_MS rr := dec_PDU_ML3_NW_MS(without_plen);
+               if (match(rr, tr_PAGING_REQ1)) {
+                       num_paging_rcv_msgs := num_paging_rcv_msgs + 1;
+                       num_paging_rcv_ids := num_paging_rcv_ids + 1;
+                       if 
(isvalue(rr.msgs.rrm.pagingReq_Type1.mobileIdentity2)) {
+                               num_paging_rcv_ids := num_paging_rcv_ids + 1;
+                       }
+               } else if (match(rr, tr_PAGING_REQ2)) {
+                       num_paging_rcv_msgs := num_paging_rcv_msgs + 1;
+                       if (not 
tmsi_is_dummy(rr.msgs.rrm.pagingReq_Type2.mobileIdentity1)) {
+                               num_paging_rcv_ids := num_paging_rcv_ids + 1;
+                       }
+                       if (not 
tmsi_is_dummy(rr.msgs.rrm.pagingReq_Type2.mobileIdentity2)) {
+                               num_paging_rcv_ids := num_paging_rcv_ids + 1;
+                       }
+                       if 
(isvalue(rr.msgs.rrm.pagingReq_Type2.mobileIdentity3)) {
+                               num_paging_rcv_ids := num_paging_rcv_ids + 1;
+                       }
+               } else if (match(rr, tr_PAGING_REQ3)) {
+                       num_paging_rcv_msgs := num_paging_rcv_msgs + 1;
+                       if (not 
tmsi_is_dummy(rr.msgs.rrm.pagingReq_Type3.mobileIdentity1)) {
+                               num_paging_rcv_ids := num_paging_rcv_ids + 1;
+                       }
+                       if (not 
tmsi_is_dummy(rr.msgs.rrm.pagingReq_Type3.mobileIdentity2)) {
+                               num_paging_rcv_ids := num_paging_rcv_ids + 1;
+                       }
+                       if (not 
tmsi_is_dummy(rr.msgs.rrm.pagingReq_Type3.mobileIdentity3)) {
+                               num_paging_rcv_ids := num_paging_rcv_ids + 1;
+                       }
+                       if (not 
tmsi_is_dummy(rr.msgs.rrm.pagingReq_Type3.mobileIdentity4)) {
+                               num_paging_rcv_ids := num_paging_rcv_ids + 1;
+                       }
+               }
+               repeat;
+       }
+}
+
+type record PagingTestCfg {
+       boolean combined_ccch,
+       integer bs_ag_blks_res,
+       float load_factor,
+       boolean exp_load_ind,
+       boolean exp_overload,
+       boolean use_tmsi
+}
+
+type record PagingTestState {
+       integer num_paging_sent,
+       integer num_paging_rcv_msgs,
+       integer num_paging_rcv_ids,
+       integer num_overload
+}
+
+/* receive + ignore RSL RF RES IND */
+altstep as_rsl_res_ind() runs on test_CT {
+       [] RSL_CCHAN.receive(tr_RSL(tr_RSL_RF_RES_IND)) {
+               repeat;
+       }
+}
+
+/* Helper function for paging related testing */
+private function f_TC_paging(PagingTestCfg cfg) runs on test_CT return 
PagingTestState {
+       f_init(testcasename());
+       f_init_l1ctl();
+       f_l1_tune(L1CTL);
+
+       var PagingTestState st := {
+               num_paging_sent := 0,
+               num_paging_rcv_msgs := 0,
+               num_paging_rcv_ids := 0,
+               num_overload := 0
+       };
+
+       var float max_pch_blocks_per_sec := 
f_pch_block_rate_est(cfg.combined_ccch, cfg.bs_ag_blks_res);
+       var float max_pch_imsi_per_sec;
+       if (cfg.use_tmsi) {
+               max_pch_imsi_per_sec := max_pch_blocks_per_sec * 4.0; /* Type 3 
*/
+       } else {
+               max_pch_imsi_per_sec := max_pch_blocks_per_sec * 2.0; /* Type 1 
*/
+       }
+       var float pch_blocks_per_sec := max_pch_imsi_per_sec * cfg.load_factor;
+       var float interval := 1.0 / pch_blocks_per_sec;
+       log("pch_blocks_per_sec=", pch_blocks_per_sec, " interval=", interval);
+
+       for (var integer i := 0; i < float2int(20.0/interval); i := i+1) {
+               /* build mobile Identity */
+               var MobileL3_CommonIE_Types.MobileIdentityLV mi;
+               if (cfg.use_tmsi) {
+                       mi := valueof(ts_MI_TMSI_LV(f_rnd_octstring(4)));
+               } else {
+                       mi := valueof(ts_MI_IMSI_LV(f_gen_imsi(i)));
+               }
+               var octetstring mi_enc_lv := enc_MobileIdentityLV(mi);
+               var octetstring mi_enc := substr(mi_enc_lv, 1, 
lengthof(mi_enc_lv)-1);
+
+               /* Send RSL PAGING COMMAND */
+               RSL_CCHAN.send(ts_RSL(ts_RSL_PAGING_CMD(mi_enc, i mod 4)));
+               st.num_paging_sent := st.num_paging_sent + 1;
+
+               /* Wait for interval to next PAGING COMMAND */
+               timer T_itv := interval;
+               T_itv.start;
+               alt {
+               /* check for presence of CCCH LOAD IND (paging load) */
+               [cfg.exp_overload] 
RSL_CCHAN.receive(tr_RSL(tr_RSL_PAGING_LOAD_IND(0))) {
+                       st.num_overload := st.num_overload + 1;
+                       repeat;
+                       }
+               [not cfg.exp_overload]  
RSL_CCHAN.receive(tr_RSL(tr_RSL_PAGING_LOAD_IND(0))) {
+                       setverdict(fail, "Unexpected PCH Overload");
+                       }
+               [cfg.exp_load_ind] 
RSL_CCHAN.receive(tr_RSL(tr_RSL_PAGING_LOAD_IND)) {
+                       log("Rx LOAD_IND");
+                       /* FIXME: analyze/verify interval + contents */
+                       repeat;
+                       }
+               /* check if paging requests arrive on Um side */
+               [] as_l1_count_paging(st.num_paging_rcv_msgs, 
st.num_paging_rcv_ids);
+               [] L1CTL.receive { repeat; }
+               [] T_itv.timeout { }
+               [] as_rsl_res_ind();
+               }
+       }
+
+       /* wait for max 18s for paging queue to drain (size: 200, ~ 13 per s -> 
15s) */
+       timer T_wait := 18.0;
+       T_wait.start;
+       alt {
+       [] as_l1_count_paging(st.num_paging_rcv_msgs, st.num_paging_rcv_ids);
+       [] L1CTL.receive { repeat; }
+       /* 65535 == empty paging queue, we can terminate*/
+       [] RSL_CCHAN.receive(tr_RSL(tr_RSL_PAGING_LOAD_IND(65535))) { }
+       [] RSL_CCHAN.receive(tr_RSL(tr_RSL_PAGING_LOAD_IND)) { repeat; }
+       [] T_wait.timeout {
+               setverdict(fail, "Waiting for empty paging queue");
+               }
+       [] as_rsl_res_ind();
+       }
+
+       log("num_paging_sent=", st.num_paging_sent, " rcvd_msgs=", 
st.num_paging_rcv_msgs,
+           " rcvd_ids=", st.num_paging_rcv_ids);
+       return st;
+}
+
+/* Create ~ 80% paging load (IMSI only) sustained for about 20s, verifying that
+ *  - the number of Mobile Identities on Um PCH match the number of pages on 
RSL
+ *  - that CCCH LOAD IND (PCH) are being generated
+ *  - that CCCH LOAD IND (PCH) [no load] is received after paging flood is 
over */
+testcase TC_paging_imsi_80percent() runs on test_CT {
+       var PagingTestCfg cfg := {
+               combined_ccch := true,
+               bs_ag_blks_res := 1,
+               load_factor := 0.8,
+               exp_load_ind := true,
+               exp_overload := false,
+               use_tmsi := false
+       };
+       var PagingTestState st := f_TC_paging(cfg);
+       if (st.num_paging_sent != st.num_paging_rcv_ids) {
+               setverdict(fail, "Expected ", st.num_paging_sent, " pagings but 
have ",
+                          st.num_paging_rcv_ids);
+       } else {
+               setverdict(pass);
+       }
+}
+
+/* Create ~ 80% paging load (TMSI only) sustained for about 20s, verifying that
+ *  - the number of Mobile Identities on Um PCH match the number of pages on 
RSL
+ *  - that CCCH LOAD IND (PCH) are being generated
+ *  - that CCCH LOAD IND (PCH) [no load] is received after paging flood is 
over */
+testcase TC_paging_tmsi_80percent() runs on test_CT {
+       var PagingTestCfg cfg := {
+               combined_ccch := true,
+               bs_ag_blks_res := 1,
+               load_factor := 0.8,
+               exp_load_ind := true,
+               exp_overload := false,
+               use_tmsi := true
+       };
+       var PagingTestState st := f_TC_paging(cfg);
+       if (st.num_paging_sent != st.num_paging_rcv_ids) {
+               setverdict(fail, "Expected ", st.num_paging_sent, " pagings but 
have ",
+                          st.num_paging_rcv_ids);
+       } else {
+               setverdict(pass);
+       }
+}
+
+/* Create ~ 200% paging load (IMSI only) sustained for about 20s, verifying 
that
+ *  - the number of Mobile Identities on Um PCH are ~ 82% of the number of 
pages on RSL
+ *  - that CCCH LOAD IND (PCH) are being generated and reach 0 at some point
+ *  - that CCCH LOAD IND (PCH) [no load] is received after paging flood is 
over */
+testcase TC_paging_imsi_200percent() runs on test_CT {
+       var PagingTestCfg cfg := {
+               combined_ccch := true,
+               bs_ag_blks_res := 1,
+               load_factor := 2.0,
+               exp_load_ind := true,
+               exp_overload := true,
+               use_tmsi := false
+       };
+       var PagingTestState st := f_TC_paging(cfg);
+       /* We expect about 80-85% to pass, given that we can fill the paging 
buffer of 200
+        * slots and will fully drain that buffer before returning */
+       var template integer tpl := (st.num_paging_sent*80/100 .. 
st.num_paging_sent *85/100);
+       if (not match(st.num_paging_rcv_ids, tpl)) {
+               setverdict(fail, "Expected ", tpl, " pagings but have ", 
st.num_paging_rcv_ids);
+       } else {
+               setverdict(pass);
+       }
+}
+
+/* Create ~ 200% paging load (TMSI only) sustained for about 20s, verifying 
that
+ *  - the number of Mobile Identities on Um PCH are ~ 82% of the number of 
pages on RSL
+ *  - that CCCH LOAD IND (PCH) are being generated and reach 0 at some point
+ *  - that CCCH LOAD IND (PCH) [no load] is received after paging flood is 
over */
+testcase TC_paging_tmsi_200percent() runs on test_CT {
+       var PagingTestCfg cfg := {
+               combined_ccch := true,
+               bs_ag_blks_res := 1,
+               load_factor := 2.0,
+               exp_load_ind := true,
+               exp_overload := true,
+               use_tmsi := true
+       };
+       var PagingTestState st := f_TC_paging(cfg);
+       /* We expect about 70% to pass, given that we can fill the paging 
buffer of 200
+        * slots and will fully drain that buffer before returning */
+       var template integer tpl := (st.num_paging_sent*68/100 .. 
st.num_paging_sent *72/100);
+       if (not match(st.num_paging_rcv_ids, tpl)) {
+               setverdict(fail, "Expected ", tpl, " pagings but have ", 
st.num_paging_rcv_ids);
+       } else {
+               setverdict(pass);
+       }
+}
+
+
+testcase TC_imm_ass() runs on test_CT {
+       f_init(testcasename());
+       for (var integer i := 0; i < 1000; i := i+1) {
+               var octetstring ia_enc := f_rnd_octstring(8);
+               RSL_CCHAN.send(ts_RSL(ts_RSL_IMM_ASSIGN(ia_enc, 0)));
+               f_sleep(0.02);
+       }
+       /* FIXME: check if imm.ass arrive on Um side */
+       /* FIXME: check for DELETE INDICATION */
+       f_sleep(100.0);
+}
+
+testcase TC_bcch_info() runs on test_CT {
+       f_init(testcasename());
+       /* FIXME: enable / disable individual BCCH info */
+       //ts_RSL_BCCH_INFO(si_type, info);
+       /* expect no ERROR REPORT after either of them *
+       /* negative test: ensure ERROR REPORT on unsupported types */
+}
+
+
+/* TODO Areas:
+
+* channel activation
+** with BS_Power / MS_Power, bypassing power control loop
+** on primary vs. secondary TRX
+** with encryption from initial activation on
+** with timing advance from initial activation on
+* mode modify
+** encryption
+** multirate
+* check DEACTIVATE SACCH
+* encryption command / intricate logic about tx-only/tx+rx/...
+** unsupported algorithm
+* handover detection
+* MS Power Control
+* BS Power Control
+* Physical Context
+* SACCH info modify
+* BCCH INFO (SI Broadcasting)
+* CCCH Load Indication for PCH and RACH
+* Delete Indication on AGCH overflow
+* SMS Broadcast Req / Cmd / CBCH LOad Ind
+* RF resource ind
+* IPA/speech related commands
+* error handling
+* discriminator error
+** type error
+** sequence error
+** IE duplicated?
+** IE missing
+** IE length error
+
+*/
 
 control {
        execute( TC_chan_act_stress() );
@@ -666,6 +994,10 @@
        execute( TC_meas_res_sign_sdcch4() );
        execute( TC_meas_res_sign_sdcch8() );
        execute( TC_conn_fail_crit() );
+       execute( TC_paging_imsi_80percent() );
+       execute( TC_paging_tmsi_80percent() );
+       execute( TC_paging_imsi_200percent() );
+       execute( TC_paging_tmsi_200percent() );
 }
 
 
diff --git a/library/GSM_Types.ttcn b/library/GSM_Types.ttcn
index 634af34..5884c27 100644
--- a/library/GSM_Types.ttcn
+++ b/library/GSM_Types.ttcn
@@ -219,5 +219,33 @@
        }
 }
 
+const float GSM_FRAME_DURATION := 0.12/26.0; /* 4.615 ms */
+const float GSM51_MFRAME_DURATION := 51.0 * GSM_FRAME_DURATION; /* 235.365 ms 
*/
+const float GSM51_MFRAMES_PER_SEC := 1.0 / GSM51_MFRAME_DURATION; /* 4.248 */
+
+/* number of downlink CCCH blocks per second */
+function f_ccch_blocks_per_mframe(boolean combined_ccch) return integer {
+       if (not combined_ccch) {
+               /* 9 blocks per 51 multiframe */
+               return 9;
+       } else {
+               /* 3 blocks per 51 multiframe */
+               return 3;
+       }
+}
+
+/* this ignores any possible paging combining! */
+function f_pch_block_rate_est(boolean combined_ccch, integer bs_ag_blks_res) 
return float {
+       var integer ccch_per_mframe := f_ccch_blocks_per_mframe(combined_ccch);
+       var integer pch_per_mframe := ccch_per_mframe - bs_ag_blks_res;
+       return GSM51_MFRAMES_PER_SEC * int2float(pch_per_mframe);
+}
+
+/* this ignores any possible imm.ass combining! */
+function f_agch_block_rate_est(boolean combined_ccch, integer bs_ag_blks_res) 
return float {
+       var integer ccch_per_mframe := f_ccch_blocks_per_mframe(combined_ccch);
+       return GSM51_MFRAMES_PER_SEC * int2float(bs_ag_blks_res);
+}
+
 
 } with { encode "RAW"; variant "FIELDORDER(msb)" }
diff --git a/library/L1CTL_Types.ttcn b/library/L1CTL_Types.ttcn
index f9b4fe8..61d80cf 100644
--- a/library/L1CTL_Types.ttcn
+++ b/library/L1CTL_Types.ttcn
@@ -503,7 +503,8 @@
 
        /* for matching against incoming DATA_IND */
        template L1ctlDlMessage t_L1CTL_DATA_IND(template RslChannelNr chan_nr,
-                                                template RslLinkId link_id := 
?) := {
+                                                template RslLinkId link_id := 
?,
+                                                template octetstring l2_data 
:= ?) := {
                header := t_L1ctlHeader(L1CTL_DATA_IND),
                dl_info := {
                        chan_nr := chan_nr,
@@ -516,7 +517,9 @@
                        fire_crc := ?
                },
                payload := {
-                       data_ind := ?
+                       data_ind := {
+                               payload := l2_data
+                       }
                }
        };
 
@@ -538,4 +541,6 @@
                }
        };
 
+       const octetstring c_DummyUI := 
'0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O;
+
 } with { encode "RAW" };
diff --git a/library/L3_Templates.ttcn b/library/L3_Templates.ttcn
index a614122..c2825a6 100644
--- a/library/L3_Templates.ttcn
+++ b/library/L3_Templates.ttcn
@@ -280,6 +280,74 @@
        }
 }
 
+template PDU_ML3_NW_MS tr_PAGING_REQ1(template MobileIdentityLV mi1 := ?,
+                                     template MobileIdentityTLV mi2 := *) := {
+       discriminator := '0110'B,
+       tiOrSkip := {
+               skipIndicator := '0000'B
+       },
+       msgs := {
+               rrm := {
+                       pagingReq_Type1 := {
+                               messageType := '00100001'B,
+                               pageMode := ?,
+                               channelNeeded := ?,
+                               mobileIdentity1 := mi1,
+                               mobileIdentity2 := mi2,
+                               p1RestOctets := ?
+                       }
+               }
+       }
+}
+
+template PDU_ML3_NW_MS tr_PAGING_REQ2(template TMSIP_TMSI_V mi1 := ?,
+                                     template TMSIP_TMSI_V mi2 := ?,
+                                     template MobileIdentityTLV mi3 := *) := {
+       discriminator := '0110'B,
+       tiOrSkip := {
+               skipIndicator := '0000'B
+       },
+       msgs := {
+               rrm := {
+                       pagingReq_Type2 := {
+                               messageType := '00100010'B,
+                               pageMode := ?,
+                               channelNeeded := ?,
+                               mobileIdentity1 := mi1,
+                               mobileIdentity2 := mi2,
+                               mobileIdentity3 := mi3,
+                               p2RestOctets := ?
+                       }
+               }
+       }
+}
+
+template PDU_ML3_NW_MS tr_PAGING_REQ3(template TMSIP_TMSI_V mi1 := ?,
+                                     template TMSIP_TMSI_V mi2 := ?,
+                                     template TMSIP_TMSI_V mi3 := ?,
+                                     template TMSIP_TMSI_V mi4 := ?) := {
+       discriminator := '0110'B,
+       tiOrSkip := {
+               skipIndicator := '0000'B
+       },
+       msgs := {
+               rrm := {
+                       pagingReq_Type3 := {
+                               messageType := '00100100'B,
+                               pageMode := ?,
+                               channelNeeded := ?,
+                               mobileIdentity1 := mi1,
+                               mobileIdentity2 := mi2,
+                               mobileIdentity3 := mi3,
+                               mobileIdentity4 := mi4,
+                               p3RestOctets := ?
+                       }
+               }
+       }
+}
+
+
+
 /* Send template for PAGING RESPONSE */
 template (value) PDU_ML3_MS_NW ts_PAG_RESP(MobileIdentityLV mi_lv) := {
        discriminator := '0000'B, /* overwritten */
diff --git a/library/RSL_Types.ttcn b/library/RSL_Types.ttcn
index 8fb44ad..5366b31 100644
--- a/library/RSL_Types.ttcn
+++ b/library/RSL_Types.ttcn
@@ -392,6 +392,15 @@
                access_count := acc
        }
 
+       template RSL_IE_RachLoad tr_RSL_IE_RachLoad(template uint16_t slot,
+                                                   template uint16_t busy,
+                                                   template uint16_t acc) := {
+               len := ?, /* overwritten */
+               slot_count := slot,
+               busy_count := busy,
+               access_count := acc
+       }
+
        /* 9.3.19 */
        type record RSL_IE_RequestRef {
                OCT1            ra,
@@ -1149,6 +1158,17 @@
                        t_RSL_IE(RSL_IE_RACH_LOAD, RSL_IE_Body:{rach_load := 
ts_RSL_IE_RachLoad(slot_ct, busy_ct, acc_ct)})
                }
        }
+       template RSL_Message tr_RSL_RACH_LOAD_IND(template uint16_t slot_ct := 
?,
+                                                 template uint16_t busy_ct := 
?,
+                                                 template uint16_t acc_ct) := {
+               msg_disc := ts_RSL_MsgDisc(RSL_MDISC_CCHAN, false),
+               msg_type := RSL_MT_CCCH_LOAD_IND,
+               ies := {
+                       tr_RSL_IE(RSL_IE_Body:{chan_nr := t_RslChanNr_RACH(0)}),
+                       tr_RSL_IE(RSL_IE_Body:{rach_load := 
tr_RSL_IE_RachLoad(slot_ct, busy_ct, acc_ct)})
+               }
+       }
+
        template RSL_Message ts_RSL_PAGING_LOAD_IND(uint16_t buffer_space) := {
                msg_disc := ts_RSL_MsgDisc(RSL_MDISC_CCHAN, false),
                msg_type := RSL_MT_CCCH_LOAD_IND,
@@ -1157,6 +1177,15 @@
                        t_RSL_IE(RSL_IE_PAGING_LOAD, RSL_IE_Body:{paging_load 
:= buffer_space})
                }
        }
+       template RSL_Message tr_RSL_PAGING_LOAD_IND(template uint16_t 
buffer_space := ?) := {
+               msg_disc := ts_RSL_MsgDisc(RSL_MDISC_CCHAN, false),
+               msg_type := RSL_MT_CCCH_LOAD_IND,
+               ies := {
+                       tr_RSL_IE(RSL_IE_Body:{chan_nr := 
t_RslChanNr_PCH_AGCH(0)}),
+                       tr_RSL_IE(RSL_IE_Body:{paging_load := buffer_space})
+               }
+       }
+
 
        /* 8.5.3 BTS -> BSC */
        template RSL_Message ts_RSL_CHAN_RQD(OCT1 ra, GsmFrameNumber fn, 
uint8_t acc_del := 0) := {
@@ -1228,6 +1257,22 @@
                }
        }
 
+       template RSL_Message tr_RSL_RF_RES_IND := {
+               msg_disc := ts_RSL_MsgDisc(RSL_MDISC_TRX_MGMT, false),
+               msg_type := RSL_MT_RF_RES_IND,
+               ies := *
+       }
+
+       /* 8.6.2 BTS <- BSC */
+       template RSL_Message ts_RSL_SACCH_FILL(RSL_IE_SysinfoType si_type, 
octetstring l3_info) := {
+               msg_disc := ts_RSL_MsgDisc(RSL_MDISC_TRX_MGMT, false),
+               msg_type := RSL_MT_SACCH_FILL,
+               ies := {
+                       t_RSL_IE(RSL_IE_SYSINFO_TYPE, RSL_IE_Body:{sysinfo_type 
:= si_type}),
+                       t_RSL_IE(RSL_IE_L3_INFO, RSL_IE_Body:{l3_info := 
ts_RSL_L16V(l3_info)})
+               }
+       }
+
        /* 8.6.4 BTS -> BSC */
        template RSL_Message ts_RSL_ERROR_REPORT(RSL_Cause cause) := {
                msg_disc := ts_RSL_MsgDisc(RSL_MDISC_CCHAN, false),

-- 
To view, visit https://gerrit.osmocom.org/6886
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I0b80b72bdab3d80d915296d70e1174623fbd8610
Gerrit-PatchSet: 1
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <[email protected]>

Reply via email to