diff options
author | Harald Welte <laforge@gnumonks.org> | 2018-03-02 23:37:51 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2018-03-12 14:23:57 +0000 |
commit | 7024baa66cc1d7fc4360a50b2787ea0bb93e75ab (patch) | |
tree | 932b6714a45dadc9778014a996a7b2fbdb53a36e | |
parent | fd445c34fe47349f9576b6a8e4c53372e2ca8a59 (diff) |
gprs_gb: working Uplink PACKET_CONTROL_ACK against OsmoPCU
Change-Id: I2c7d0eb9371911e28f328caeaed63cb8ec311ac1
-rw-r--r-- | Common.cfg | 2 | ||||
-rw-r--r-- | gprs_gb/Test.ttcn | 81 | ||||
-rw-r--r-- | library/L1CTL_Types.ttcn | 22 | ||||
-rw-r--r-- | library/LAPDm_RAW_PT.ttcn | 43 | ||||
-rw-r--r-- | library/Osmocom_Gb_Types.ttcn | 4 | ||||
-rw-r--r-- | library/RLCMAC_CSN1_Types.ttcn | 12 | ||||
-rw-r--r-- | library/RLCMAC_Types.ttcn | 13 |
7 files changed, 146 insertions, 31 deletions
@@ -9,7 +9,7 @@ TCPDUMP_STOP := $TTCN3_HACKS_PATH"/ttcn3-tcpdump-stop.sh" SourceInfoFormat := Single; LogSourceInfo := Yes; LoggerPlugins := { JUnitLogger := "libjunitlogger2" } -#FileMask := LOG_ALL | TTCN_DEBUG | TTCN_MATCHING | DEBUG_ENCDEC; +FileMask := LOG_ALL | TTCN_DEBUG | TTCN_MATCHING | DEBUG_ENCDEC; #ConsoleMask := ERROR | WARNING | TESTCASE | TTCN_MATCHING | DEBUG_ENCDEC [EXTERNAL_COMMANDS] diff --git a/gprs_gb/Test.ttcn b/gprs_gb/Test.ttcn index 7251ef90..8741e863 100644 --- a/gprs_gb/Test.ttcn +++ b/gprs_gb/Test.ttcn @@ -17,8 +17,8 @@ module Test { modulepar { BssgpConfig mp_gb_cfg := { - nsei := 96, - bvci := 196, + nsei := 1234, + bvci := 1234, cell_id := { ra_id := { lai := { @@ -33,16 +33,16 @@ module Test { } type record MmContext { - octetstring imsi optional, + hexstring imsi optional, GprsTlli tlli, uint9_t n_u }; - type component dummy_CT { + + type component dummy_CT extends BSSGP_Client_CT { var lapdm_CT lapdm_component; port LAPDm_PT L1; - port BSSGP_PT BSSGP; var NS_CT ns_component; var BSSGP_CT bssgp_component; @@ -64,6 +64,7 @@ module Test { bssgp_component := BSSGP_CT.create; /* connect our BSSGP port to the BSSGP Emulation */ connect(self:BSSGP, bssgp_component:BSSGP_SP); + connect(self:BSSGP_PROC, bssgp_component:BSSGP_PROC); /* connect lower-end of BSSGP with BSSGP_CODEC_PORT (maps to NS_PT*/ connect(bssgp_component:BSCP, ns_component:NS_SP); /* connect lower-end of NS emulation to NS_CODEC_PORT (on top of IPl4) */ @@ -174,7 +175,7 @@ module Test { /* Establish BSSGP connection to PCU */ function f_bssgp_establish() runs on dummy_CT { - timer T:= 60.0; + timer T:= 10.0; f_init(); T.start @@ -251,9 +252,23 @@ module Test { } } template RlcmacUlBlock t_RLCMAC_UL_DATA_TLLI(template uint5_t tfi, template uint4_t cv, template uint7_t bsn, - template LlcBlocks blocks := {}, template boolean stall := false, template GprsTlli tlli) modifies t_RLCMAC_UL_DATA := { + template LlcBlocks blocks := {}, template boolean stall := false, template GprsTlli tlli) := { data := { - tlli := tlli + mac_hdr := { + payload_type := MAC_PT_RLC_DATA, + countdown := cv, + stall_ind := false, + retry := false, + spare := '0'B, + pfi_ind := false, + tfi := tfi, + tlli_ind := true, + bsn := bsn, + e := false + }, + tlli := tlli, + pfi := omit, + blocks := blocks } } @@ -338,37 +353,65 @@ uint3_t usf) := { return tlli; } + /* Compute the frame number of the uplink block based on current fn + rrbp */ + function f_rrbp_fn(GsmFrameNumber fn, MacRrbp rrbp) return GsmFrameNumber { + var integer add; + select (rrbp) { + case (RRBP_Nplus13_mod_2715648) { + add := 13; + } + case (RRBP_Nplus17_or_18_mod_2715648) { + add := 17; /* FIXME: What about 'or 18'? */ + } + case (RRBP_Nplus21_or_22_mod_2715648) { + add := 21; /* FIXME: What about 'or 22'? */ + } + case (RRBP_Nplus26_mod_2715648) { + add := 26; + } + } + return (fn + add) mod 2715648; + } + /* Send a single Uplink Block via Um; Verify reception on BSSGP; Expect UL_ACK on Um */ function f_single_ul_block(GprsCodingScheme cs) runs on dummy_CT { - var GprsTlli tlli := f_random_tlli(); var octetstring payload := '01020304'O; + var PDU_LLC llc := valueof(ts_LLC_UI(payload, c_LLC_SAPI_LLGMM, '0'B, g_mmctx.n_u)); + var octetstring llc_enc := enc_PDU_LLC(llc); + var RLCMAC_ph_data_ind dl; /* establish upling TBF */ f_establish_ul_tbf(); /* Generate LLC PDU consisting of single RLC block and send it via simulated MS */ - var template RlcmacUlBlock blk := t_RLCMAC_UL_DATA_TLLI(0, 0, 0, {t_RLCMAC_LLCBLOCK(payload)}, false, tlli); - L1.send(RLCMAC_ph_data_req:{tbf_id := 0, cs := cs, block := blk}); + var template RlcmacUlBlock blk := t_RLCMAC_UL_DATA_TLLI(0, 0, 0, {t_RLCMAC_LLCBLOCK(llc_enc)}, false, g_mmctx.tlli); + L1.send(RLCMAC_ph_data_req:{dyn:={tbf_id := 0, cs := cs, block := blk}}); /* ensure that this LLC-PDU arrives from the right TLLI at the (simulated) SGSN */ - BSSGP.receive(tr_BD_BSSGP(tr_BSSGP_UL_UD(tlli, ?, payload))); + BSSGP.receive(tr_BD_BSSGP(tr_BSSGP_UL_UD(g_mmctx.tlli, ?, llc_enc))); /* ensure the MS eceives an UL_ACK_NACK */ alt { - [] L1.receive(RLCMAC_ph_data_ind:{cs:=?, block:=tr_RLCMAC_ACK_NACK(0, tlli)}) { }; - [] L1.receive { repeat; }; + [] L1.receive(RLCMAC_ph_data_ind:{cs:=?, ts_nr:=?, fn:=?, block:=tr_RLCMAC_ACK_NACK(0, g_mmctx.tlli)}) -> value dl { + log("found matching ACK/NACK"); + /* send CTRL ACK in uplink */ + var GsmFrameNumber ul_fn := f_rrbp_fn(dl.fn, dl.block.ctrl.mac_hdr.rrbp); + var RlcmacUlCtrlMsg ctrl_ack := valueof(ts_RlcMacUlCtrl_PKT_CTRL_ACK(g_mmctx.tlli)); + 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, 0}, ul_block)); + } + [] L1.receive { repeat; }; } - log("found matching ACK/NACK"); - /* send CTRL ACK in uplink */ - //L1.send(FIXME); } testcase TC_rach() runs on dummy_CT { - var hexstring imsi := '262420123456789'H; var BssgpBvci bvci := 196; - var GsmTmsi tmsi := hex2int('01234567'H); + g_mmctx.imsi := '262420123456789'H; + g_mmctx.tlli := f_random_tlli(); f_init(); + f_bssgp_client_register(g_mmctx.imsi, g_mmctx.tlli, mp_gb_cfg.cell_id); + f_bssgp_establish(); f_single_ul_block(CS1); diff --git a/library/L1CTL_Types.ttcn b/library/L1CTL_Types.ttcn index f853057b..33a01a81 100644 --- a/library/L1CTL_Types.ttcn +++ b/library/L1CTL_Types.ttcn @@ -8,6 +8,8 @@ module L1CTL_Types { import from GSM_RR_Types all; import from Osmocom_Types all; + type uint32_t uint32_le with { variant "BYTEORDER(first)" }; + type enumerated L1ctlMsgType { L1CTL_NONE, L1CTL_FBSB_REQ, @@ -143,7 +145,9 @@ module L1CTL_Types { type record L1ctlDataInd { octetstring payload length(23) - } with { variant "" }; + } with { + variant (payload) "BYTEORDER(first)" + }; type union L1ctlDlPayload { L1ctlFbsbConf fbsb_conf, @@ -153,7 +157,9 @@ module L1CTL_Types { L1ctlTrafficReq traffic_ind, L1ctlTbfCfgReq tbf_cfg_conf, octetstring other - } with { variant "" }; + } with { + variant (other) "BYTEORDER(first)" + }; type record L1ctlDlMessage { L1ctlHeader header, @@ -196,7 +202,7 @@ module L1CTL_Types { L1ctlGprsCs cs, uint8_t ts_nr, OCT1 padding, - uint32_t fn, + uint32_le fn, Arfcn arfcn, OCT2 padding2 } with { variant "" }; @@ -277,7 +283,9 @@ module L1CTL_Types { type record L1ctlTrafficReq { octetstring data length(TRAFFIC_DATA_LEN) - } with { variant "" }; + } with { + variant (data) "BYTEORDER(first)" + } type record length(8) of uint8_t TfiUsfArr; @@ -300,7 +308,9 @@ module L1CTL_Types { L1ctlTrafficReq traffic_req, L1ctlTbfCfgReq tbf_cfg_req, octetstring other - } with { variant "" }; + } with { + variant (other) "BYTEORDER(first)" + }; type record L1ctlUlMessage { L1ctlHeader header, @@ -586,4 +596,6 @@ module L1CTL_Types { const octetstring c_DummyUI := '0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O; +/* We use "BYTEORDER(last)" so we get little-endian integers. Unfortuantely, this also + switches the byte ordering in octet strings, so we need to explicitly annotate them :/ */ } with { encode "RAW" }; diff --git a/library/LAPDm_RAW_PT.ttcn b/library/LAPDm_RAW_PT.ttcn index 229aff04..ab995389 100644 --- a/library/LAPDm_RAW_PT.ttcn +++ b/library/LAPDm_RAW_PT.ttcn @@ -47,13 +47,27 @@ module LAPDm_RAW_PT { /* PH-DATA.ind / PH-DATA.req */ type record RLCMAC_ph_data_ind { GprsCodingScheme cs, + uint8_t ts_nr, + GsmFrameNumber fn, RlcmacDlBlock block } - type record RLCMAC_ph_data_req { + type record RLCMAC_ph_data_req_dyn { uint8_t tbf_id, GprsCodingScheme cs, RlcmacUlBlock block } + type record RLCMAC_ph_data_req_abs { + uint8_t tbf_id, + GprsCodingScheme cs, + uint8_t ts_nr, + GsmFrameNumber fn, + Arfcn arfcn, + RlcmacUlBlock block + } + type union RLCMAC_ph_data_req { + RLCMAC_ph_data_req_dyn dyn, + RLCMAC_ph_data_req_abs abs + } /* port from our (internal) point of view */ type port LAPDm_SP_PT message { @@ -223,6 +237,19 @@ module LAPDm_RAW_PT { } }; + template (value) RLCMAC_ph_data_req ts_PH_DATA_ABS(uint8_t tbf_id, GprsCodingScheme cs, + uint8_t ts, uint32_t fn, Arfcn arfcn, + RlcmacUlBlock block) := { + abs := { + tbf_id := tbf_id, + cs := CS1, /* FIXME */ + ts_nr := ts, + fn := fn, + arfcn := arfcn, + block := block + } + } + private function f_establish_tbf(uint8_t ra) runs on lapdm_CT { var ImmediateAssignment imm_ass; var GsmFrameNumber rach_fn; @@ -377,6 +404,8 @@ module LAPDm_RAW_PT { /* 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); + rpdi.fn := dl.dl_info.frame_nr; + rpdi.ts_nr := dl.dl_info.chan_nr.tn; rpdi.cs := CS1; /* FIXME */ log("RPDI: ", rpdi); LAPDM_SP.send(rpdi); @@ -387,9 +416,15 @@ module LAPDm_RAW_PT { /* encode + forward any blocks from L23 to L1 */ [] LAPDM_SP.receive(RLCMAC_ph_data_req:?) -> value rpdr { var octetstring buf; - - buf := enc_RlcmacUlBlock(rpdr.block); - L1CTL.send(t_L1CTL_DATA_TBF_REQ(buf, L1CTL_CS1, rpdr.tbf_id)); + if (ischosen(rpdr.dyn)) { + buf := enc_RlcmacUlBlock(rpdr.dyn.block); + L1CTL.send(t_L1CTL_DATA_TBF_REQ(buf, L1CTL_CS1, rpdr.dyn.tbf_id)); + } else { + buf := enc_RlcmacUlBlock(rpdr.abs.block); + L1CTL.send(t_L1CTL_DATA_ABS_REQ(buf, rpdr.abs.arfcn, + rpdr.abs.ts_nr, rpdr.abs.fn, + L1CTL_CS1, rpdr.abs.tbf_id)); + } } /* FIXME: release TBF mode */ diff --git a/library/Osmocom_Gb_Types.ttcn b/library/Osmocom_Gb_Types.ttcn index f943c9c0..3de74271 100644 --- a/library/Osmocom_Gb_Types.ttcn +++ b/library/Osmocom_Gb_Types.ttcn @@ -301,8 +301,8 @@ octetstring sdu) := { } template LLC_PDU tr_BSSGP_LLC_PDU(template octetstring pdu := ?) := { - iEI := '0D'O, - ext := '1'B, + iEI := '0E'O, + ext := ?, lengthIndicator := ?, lLC_PDU := pdu } diff --git a/library/RLCMAC_CSN1_Types.ttcn b/library/RLCMAC_CSN1_Types.ttcn index 2335c29d..95b58386 100644 --- a/library/RLCMAC_CSN1_Types.ttcn +++ b/library/RLCMAC_CSN1_Types.ttcn @@ -513,4 +513,16 @@ module RLCMAC_CSN1_Types { variant (relative_k) "PRESENCE(presence = '1'B)" }; + template (value) RlcmacUlCtrlMsg ts_RlcMacUlCtrl_PKT_CTRL_ACK(GprsTlli tlli, + CtrlAck ack := MS_RCVD_TWO_RLC_SAME_RTI_DIFF_RBSN) := { + msg_type := PACKET_CONTROL_ACK, + u := { + ctrl_ack := { + tlli := tlli, + ctrl_ack := ack + } + } + } + + } with { encode "RAW"; variant "FIELDORDER(msb)" variant "BYTEORDER(last)" }; diff --git a/library/RLCMAC_Types.ttcn b/library/RLCMAC_Types.ttcn index a30a43cd..937aa7b2 100644 --- a/library/RLCMAC_Types.ttcn +++ b/library/RLCMAC_Types.ttcn @@ -226,4 +226,17 @@ module RLCMAC_Types { external function enc_RlcmacDlBlock(in RlcmacDlBlock si) return octetstring; external function dec_RlcmacDlBlock(in octetstring stream) return RlcmacDlBlock; + template (value) RlcmacUlBlock ts_RLC_UL_CTRL_ACK(RlcmacUlCtrlMsg ctrl, + MacPayloadType pt := MAC_PT_RLCMAC_NO_OPT, + boolean retry := false) := { + ctrl := { + mac_hdr := { + payload_type := pt, + spare := '00000'B, + retry := retry + }, + payload := ctrl + } + } + } with { encode "RAW"; variant "FIELDORDER(msb)" } |