Harald Welte has submitted this change and it was merged.

Change subject: pcu: First DL TBF hack
......................................................................


pcu: First DL TBF hack

Change-Id: Ib3f09e125a7a4492d9072f8e9f5896eaac7ed03b
---
M library/GSM_RR_Types.ttcn
M library/L1CTL_PortType.ttcn
M library/LAPDm_RAW_PT.ttcn
M library/RLCMAC_CSN1_Types.ttcn
M library/RLCMAC_Types.ttcn
M pcu/PCU_Tests.ttcn
6 files changed, 279 insertions(+), 20 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved; Verified
  Jenkins Builder: Verified



diff --git a/library/GSM_RR_Types.ttcn b/library/GSM_RR_Types.ttcn
index 75be6f8..b1e6809 100644
--- a/library/GSM_RR_Types.ttcn
+++ b/library/GSM_RR_Types.ttcn
@@ -706,6 +706,57 @@
                }
        };
 
+       template ImmediateAssignment t_IMM_ASS_TBF_DL(template GprsTlli tlli) 
:= {
+               ded_or_tbf := {
+                       spare := ?,
+                       tma := ?,
+                       downlink := ?,
+                       tbf := true
+               },
+               page_mode := ?,
+               chan_desc := omit,
+               pkt_chan_desc := {
+                       channel_Type_spare := ?,
+                       tn := ?,
+                       tsc := ?,
+                       presence := ?,
+                       zero := *,
+                       one := omit
+               },
+               req_ref := ?,
+               timing_advance := ?,
+               mobile_allocation := ?,
+               rest_octets := {
+                       presence := '11'B,
+                       ll := omit,
+                       lh := omit,
+                       hl := omit,
+                       hh := {
+                               presence := '01'B,
+                               ul := omit,
+                               dl := {
+                                       tlli := tlli,
+                                       group1_present := ?,
+                                       group1 := *,
+                                       ta_index_present := ?,
+                                       ta_index := *,
+                                       tbf_starting_time_present := ?,
+                                       tbf_starting_time := *,
+                                       p0_present := ?,
+                                       p0 := *,
+                                       pr_mode := *
+                               }
+                       }
+               }
+       };
+
+       template GsmRrMessage t_RR_IMM_ASS_TBF_DL(template GprsTlli tlli) := {
+               header := t_RrHeader(IMMEDIATE_ASSIGNMENT, ?),
+               payload := {
+                       imm_ass := t_IMM_ASS_TBF_DL(tlli)
+               }
+       };
+
 
 
 } with { encode "RAW" ; variant "FIELDORDER(msb)" }
diff --git a/library/L1CTL_PortType.ttcn b/library/L1CTL_PortType.ttcn
index 2775e19..eadc74a 100644
--- a/library/L1CTL_PortType.ttcn
+++ b/library/L1CTL_PortType.ttcn
@@ -90,6 +90,28 @@
                return rr.payload.imm_ass;
        }
 
+       function f_L1CTL_WAIT_IMM_ASS_TBF_DL(L1CTL_PT pt, GprsTlli tlli) return 
ImmediateAssignment {
+               var L1ctlDlMessage dl;
+               var GsmRrMessage rr;
+               timer T := 10.0;
+               T.start;
+               alt {
+                       [] 
pt.receive(t_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0))) -> value dl {
+                               rr := 
dec_GsmRrMessage(dl.payload.data_ind.payload);
+                               log("PCH/AGCN DL RR: ", rr);
+                               if (match(rr, t_RR_IMM_ASS_TBF_DL(tlli))) {
+                                       log("Received IMM.ASS for our TLLI!");
+                               } else {
+                                       repeat;
+                               }
+                       };
+                       [] pt.receive { repeat };
+                       [] T.timeout { setverdict(fail, "Timeout waiting for 
IMM ASS") };
+               }
+               T.stop;
+               return rr.payload.imm_ass;
+       }
+
        function f_L1CTL_TBF_CFG(L1CTL_PT pt, boolean is_uplink, TfiUsfArr 
tfi_usf) {
                timer T := 2.0;
                T.start;
diff --git a/library/LAPDm_RAW_PT.ttcn b/library/LAPDm_RAW_PT.ttcn
index ab99538..f5d1926 100644
--- a/library/LAPDm_RAW_PT.ttcn
+++ b/library/LAPDm_RAW_PT.ttcn
@@ -26,7 +26,21 @@
                charstring err optional
        }
 
-       type record TBF_establish_res {
+       type record length(8) of uint8_t TfiList;
+       type record TbfPars {
+               GsmArfcn        arfcn optional,
+               /* Temporary Flow Identifier for each TN */
+               TfiList         tfi
+       }
+       type record length(8) of TbfPars TbfParsPerTs;
+
+       template TbfPars t_TbfParsInit := {
+               arfcn := omit,
+               tfi := { 255, 255, 255, 255, 255, 255, 255, 255 }
+       }
+
+       type record TBF_UL_establish_res {
+               TbfPars pars optional,
                charstring err optional
        }
 
@@ -40,8 +54,15 @@
                LapdmFrame lapdm
        }
 
-       type record TBF_establish_req {
+       type integer TbfNr (0..7);      /* maximum of 8 concurrent TBF per 
direction */
+       type record TBF_UL_establish_req {
+               TbfNr tbf_nr,
                uint8_t ra
+       }
+
+       type record TBF_DL_establish_req {
+               TbfNr tbf_nr,
+               TbfPars pars
        }
 
        /* PH-DATA.ind / PH-DATA.req */
@@ -74,11 +95,12 @@
                in      BCCH_tune_req,
                        DCCH_establish_req,
                        DCCH_release_req,
-                       TBF_establish_req,
+                       TBF_UL_establish_req,
+                       TBF_DL_establish_req,
                        RLCMAC_ph_data_req,
                        LAPDm_ph_data;
                out     DCCH_establish_res,
-                       TBF_establish_res,
+                       TBF_UL_establish_res,
                        RLCMAC_ph_data_ind,
                        LAPDm_ph_data;
        } with {extension "internal"};
@@ -86,13 +108,14 @@
        /* port from user (external) point of view */
        type port LAPDm_PT message {
                in      DCCH_establish_res,
-                       TBF_establish_res,
+                       TBF_UL_establish_res,
                        RLCMAC_ph_data_ind,
                        LAPDm_ph_data;
                out     BCCH_tune_req,
                        DCCH_establish_req,
                        DCCH_release_req,
-                       TBF_establish_req,
+                       TBF_UL_establish_req,
+                       TBF_DL_establish_req,
                        RLCMAC_ph_data_req,
                        LAPDm_ph_data;
        } with {extension "internal"};
@@ -124,6 +147,9 @@
 
                /* channel description of the currently active DCH */
                var ChannelDescription chan_desc;
+
+               var TbfParsPerTs g_tbf_ul;
+               var TbfParsPerTs g_tbf_dl;
        };
 
        /* wrapper function to log state transitions */
@@ -286,6 +312,51 @@
                set_ph_state(PH_STATE_BCH);
        }
 
+       /* Establish TBF / packet transfer mode */
+       private altstep as_tbf_ul_est() runs on lapdm_CT {
+               var TBF_UL_establish_req tbf_ul_req;
+               [] LAPDM_SP.receive(TBF_UL_establish_req:?) -> value tbf_ul_req 
{
+                       var TbfNr tbf_nr := tbf_ul_req.tbf_nr;
+                       var TBF_UL_establish_res res;
+                       if (isvalue(g_tbf_ul[tbf_nr].arfcn)) {
+                               setverdict(fail, "Cannot establish UL TBF ID ", 
tbf_nr, ": BUSY");
+                               self.stop;
+                       }
+                       f_establish_tbf(tbf_ul_req.ra);
+                       if (ph_state == PH_STATE_TBF) {
+                               g_tbf_ul[tbf_nr] := valueof(t_TbfParsInit); /* 
FIXME: Actual TFI[s] */
+                               log("Established UL TBF ", tbf_nr);
+                               res := { pars := g_tbf_ul[tbf_nr], err := omit 
};
+                       } else {
+                               res := { pars := omit, err := "Unable to 
establish UL TBF" };
+                       }
+                       LAPDM_SP.send(res);
+               }
+       }
+
+       private altstep as_tbf_dl_est() runs on lapdm_CT {
+               var TBF_DL_establish_req tbf_dl_req;
+               [] LAPDM_SP.receive(TBF_DL_establish_req:?) -> value tbf_dl_req 
{
+                       var TbfNr tbf_nr := tbf_dl_req.tbf_nr;
+                       if (isvalue(g_tbf_dl[tbf_nr].arfcn)) {
+                               setverdict(fail, "Cannot establish DL TBF ID ", 
tbf_nr, ": BUSY");
+                               self.stop;
+                       }
+                       g_tbf_dl[tbf_nr] := tbf_dl_req.pars;
+                       f_L1CTL_TBF_CFG(L1CTL, false, tbf_dl_req.pars.tfi);
+                       set_ph_state(PH_STATE_TBF);
+                       log("Established DL TBF ", tbf_nr, ": ", 
tbf_dl_req.pars);
+               }
+       }
+
+       private function f_init_tbf() runs on lapdm_CT {
+               var integer i;
+               for (i := 0; i < 8; i := i+1) {
+                       g_tbf_ul[i] := valueof(t_TbfParsInit);
+                       g_tbf_dl[i] := valueof(t_TbfParsInit);
+               }
+       }
+
        function ScanEvents() runs on lapdm_CT {
                var L1ctlDlMessage dl;
                var BCCH_tune_req bt;
@@ -294,7 +365,8 @@
                var RLCMAC_ph_data_req rpdr;
                var DCCH_establish_req est_req;
                var DCCH_establish_res est_res;
-               var TBF_establish_req tbf_req;
+
+               f_init_tbf();
 
                while (true) {
                if (ph_state == PH_STATE_NULL) {
@@ -341,17 +413,8 @@
                                LAPDM_SP.send(res);
                        }
 
-                       /* Establish TBF / packet transfer mode */
-                       [] LAPDM_SP.receive(TBF_establish_req:?) -> value 
tbf_req {
-                               var TBF_establish_res res;
-                               f_establish_tbf(tbf_req.ra);
-                               if (ph_state == PH_STATE_TBF) {
-                                       res := { err := omit };
-                               } else {
-                                       res := { err := "Unable to establish 
TBF" };
-                               }
-                               LAPDM_SP.send(res);
-                       }
+                       [] as_tbf_ul_est();
+                       [] as_tbf_dl_est();
 
                        [] LAPDM_SP.receive {}
                        [] L1CTL.receive {}
@@ -404,6 +467,7 @@
                        /* decode + forward any blocks from L1 to L23*/
                        [] L1CTL.receive(t_L1CTL_DATA_IND(t_RslChanNr_PDCH(?))) 
-> value dl {
                                rpdi.block := 
dec_RlcmacDlBlock(dl.payload.data_ind.payload);
+                               /* FIXME: Filter based on g_tbf_dl */
                                rpdi.fn := dl.dl_info.frame_nr;
                                rpdi.ts_nr := dl.dl_info.chan_nr.tn;
                                rpdi.cs := CS1; /* FIXME */
@@ -427,10 +491,14 @@
                                }
                        }
 
+                       [] as_tbf_ul_est();
+                       [] as_tbf_dl_est();
+
                        /* FIXME: release TBF mode */
                        [] LAPDM_SP.receive(DCCH_release_req:?) {
                                /* go back to BCCH */
                                f_release_tbf();
+                               f_init_tbf();
                        }
 
                        }
diff --git a/library/RLCMAC_CSN1_Types.ttcn b/library/RLCMAC_CSN1_Types.ttcn
index 95b5838..fbd01d4 100644
--- a/library/RLCMAC_CSN1_Types.ttcn
+++ b/library/RLCMAC_CSN1_Types.ttcn
@@ -524,5 +524,31 @@
                }
        }
 
+       private const ILevel iNone := {
+               presence := '0'B,
+               i_level := omit
+       }
+       private const ChannelQualityReport c_ChQualRep_default := {
+               c_value := 0,
+               rxqual := 0,
+               sign_var := 0,
+               i_levels := { iNone, iNone, iNone, iNone, iNone, iNone, iNone, 
iNone }
+       }
+       template (value) RlcmacUlCtrlMsg ts_RlcMacUlCtrl_PKT_DL_ACK(uint5_t 
dl_tfi,
+                                                                   
AckNackDescription andesc,
+                                       ChannelQualityReport qual_rep := 
c_ChQualRep_default) := {
+               msg_type := PACKET_DL_ACK_NACK,
+               u := {
+                       dl_ack_nack := {
+                               dl_tfi := dl_tfi,
+                               ack_nack_desc := andesc,
+                               chreq_desc_presence := '0'B,
+                               chreq_desc := omit,
+                               ch_qual_rep := qual_rep
+                       }
+               }
+       }
+
+
 
 } with { encode "RAW"; variant "FIELDORDER(msb)" variant "BYTEORDER(last)" };
diff --git a/library/RLCMAC_Types.ttcn b/library/RLCMAC_Types.ttcn
index 78861ff..3ae1203 100644
--- a/library/RLCMAC_Types.ttcn
+++ b/library/RLCMAC_Types.ttcn
@@ -323,6 +323,21 @@
                }
        }
 
+       template RlcmacDlBlock tr_RLCMAC_DATA_RRBP := {
+               data := {
+                       mac_hdr := {
+                               mac_hdr := {
+                                       payload_type := MAC_PT_RLC_DATA,
+                                       rrbp := ?,
+                                       rrbp_valid := true,
+                                       usf := ?
+                               },
+                               hdr_ext := ?
+                       },
+                       blocks := ?
+               }
+       }
+
        /* Template for Uplink MAC Control Header */
        template UlMacCtrlHeader t_RLCMAC_UlMacCtrlH(template MacPayloadType 
pt, template boolean retry := false) := {
                payload_type := pt,
diff --git a/pcu/PCU_Tests.ttcn b/pcu/PCU_Tests.ttcn
index ef46831..12b63d6 100644
--- a/pcu/PCU_Tests.ttcn
+++ b/pcu/PCU_Tests.ttcn
@@ -16,6 +16,7 @@
        import from LAPDm_RAW_PT all;
        import from GPRS_Context all;
        import from GPRS_TBF all;
+       import from L1CTL_PortType all;
 
        modulepar {
                BssgpConfig mp_gb_cfg := {
@@ -221,12 +222,12 @@
                L1.send(tune_req);
                /* FIXME: wait for confirm */
 
-               var TBF_establish_req est_req := { ra := hex2int('7B'H) };
+               var TBF_UL_establish_req est_req := { tbf_nr := 0, ra := 
hex2int('7B'H) };
                L1.send(est_req);
                T.start;
                /* FIXME: wait for confirm */
                alt {
-                       [] L1.receive(TBF_establish_res:?) {}
+                       [] L1.receive(TBF_UL_establish_res:?) {}
                        [] L1.receive { repeat; }
                        [] T.timeout {
                                setverdict(fail, "Timeout establishing UL TBF");
@@ -526,6 +527,82 @@
                f_exit();
        }
 
+       testcase TC_dl_tbf() runs on dummy_CT {
+               g_mmctx.imsi := '262420123456789'H;
+               g_mmctx.tlli := f_random_tlli();
+               f_init();
+
+               f_establish_dl_tbf();
+
+               f_exit();
+       }
+
+       function f_wait_tbf_dl(TbfNr tbf_nr, GprsTlli tlli) runs on dummy_CT 
return ImmediateAssignment {
+               var LAPDm_ph_data ph_data;
+               var GsmRrMessage rr;
+               timer T := 10.0;
+               T.start;
+               alt {
+               [] 
L1.receive(LAPDm_ph_data:{sacch:=?,sapi:=0,lapdm:={bbis:=?}}) -> value ph_data {
+                       rr := dec_GsmRrMessage(ph_data.lapdm.bbis.payload);
+                       log("PCH/AGCH DL RR: ", rr);
+                       if (match(rr, t_RR_IMM_ASS_TBF_DL(tlli))) {
+                               var TbfPars tbf_pars := valueof(t_TbfParsInit);
+                               log("Received IMM.ASS for our TLLI!");
+                               
tbf_pars.tfi[rr.payload.imm_ass.pkt_chan_desc.tn] :=
+                                       
rr.payload.imm_ass.rest_octets.hh.dl.group1.tfi_assignment;
+                               L1.send(TBF_DL_establish_req:{tbf_nr, 
tbf_pars});
+                       } else {
+                               repeat;
+                       }
+               }
+               [] L1.receive { repeat };
+               [] T.timeout {
+                       setverdict(fail, "Timeout waiting for IMM ASS")
+                       self.stop;
+                       }
+               }
+               T.stop;
+               return rr.payload.imm_ass;
+       }
+
+       /* Establish an UL TBF: Tune to ARFCN, send RACH, receive AGCH, enable 
TBF Rx */
+       function f_establish_dl_tbf() runs on dummy_CT {
+               timer T := 5.0;
+               var BCCH_tune_req tune_req := { { false, 871 }, true };
+               L1.send(tune_req);
+               /* FIXME: wait for confirm */
+
+               /* sending a GMM PDU as DL-UNITDATA should trigger Paging + DL 
TBF Assignment */
+               tx_gmm('1'B, '01020304'O, c_LLC_SAPI_LLGMM);
+
+               /* Expect an IMM.ASS for PDCH on the AGCH */
+               f_wait_tbf_dl(0, g_mmctx.tlli);
+
+               var RLCMAC_ph_data_ind dl;
+               alt {
+               [] L1.receive(RLCMAC_ph_data_ind:{cs:=?, ts_nr:=?, fn:=?, 
block:=tr_RLCMAC_DATA_RRBP}) ->
+value dl {
+                       var uint6_t tfi := dl.block.data.mac_hdr.hdr_ext.tfi;
+                       var GsmFrameNumber ul_fn := f_rrbp_fn(dl.fn, 
dl.block.data.mac_hdr.mac_hdr.rrbp);
+                       var AckNackDescription an_desc := { /* FIXME: compute 
this based on state */
+                               final_ack := '1'B,
+                               starting_seq_nr := 0,
+                               receive_block_bitmap := 
'0000000000000000000000000000000000000000000000000000000000000001'B
+                       }
+                       var RlcmacUlCtrlMsg ctrl_ack;
+                       ctrl_ack := valueof(ts_RlcMacUlCtrl_PKT_DL_ACK(tfi, 
an_desc));
+                       var RlcmacUlBlock ul_block := 
valueof(ts_RLC_UL_CTRL_ACK(ctrl_ack));
+                       L1.send(ts_PH_DATA_ABS(0, CS1, dl.ts_nr, ul_fn, {false, 
871}, ul_block));
+                       log("Sent DL ACK: ", ul_block);
+                       }
+               [] L1.receive { repeat; }
+               }
+
+               f_sleep(10.0);
+       }
+
+
        control {
                execute(TC_selftest_bssgp());
                execute(TC_selftest_ns());

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ib3f09e125a7a4492d9072f8e9f5896eaac7ed03b
Gerrit-PatchSet: 2
Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <lafo...@gnumonks.org>
Gerrit-Reviewer: Harald Welte <lafo...@gnumonks.org>
Gerrit-Reviewer: Jenkins Builder

Reply via email to