Review at https://gerrit.osmocom.org/7152
WIP: working Uplink PACKET_CONTROL_ACK Change-Id: I2c7d0eb9371911e28f328caeaed63cb8ec311ac1 --- M Common.cfg M gprs_gb/Test.ttcn M library/L1CTL_Types.ttcn M library/LAPDm_RAW_PT.ttcn M library/NS_Emulation.ttcn M library/Osmocom_Gb_Types.ttcn M library/RLCMAC_CSN1_Types.ttcn M library/RLCMAC_Types.ttcn 8 files changed, 147 insertions(+), 32 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/52/7152/1 diff --git a/Common.cfg b/Common.cfg index 4a50420..38beb5a 100644 --- a/Common.cfg +++ b/Common.cfg @@ -9,7 +9,7 @@ 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 7251ef9..8741e86 100644 --- a/gprs_gb/Test.ttcn +++ b/gprs_gb/Test.ttcn @@ -17,8 +17,8 @@ modulepar { BssgpConfig mp_gb_cfg := { - nsei := 96, - bvci := 196, + nsei := 1234, + bvci := 1234, cell_id := { ra_id := { lai := { @@ -33,16 +33,16 @@ } 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 @@ 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 @@ /* 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 @@ } } 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 @@ 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 f853057..33a01a8 100644 --- a/library/L1CTL_Types.ttcn +++ b/library/L1CTL_Types.ttcn @@ -8,6 +8,8 @@ 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 @@ type record L1ctlDataInd { octetstring payload length(23) - } with { variant "" }; + } with { + variant (payload) "BYTEORDER(first)" + }; type union L1ctlDlPayload { L1ctlFbsbConf fbsb_conf, @@ -153,7 +157,9 @@ 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 @@ L1ctlGprsCs cs, uint8_t ts_nr, OCT1 padding, - uint32_t fn, + uint32_le fn, Arfcn arfcn, OCT2 padding2 } with { variant "" }; @@ -277,7 +283,9 @@ 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 @@ 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 @@ 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 229aff0..ab99538 100644 --- a/library/LAPDm_RAW_PT.ttcn +++ b/library/LAPDm_RAW_PT.ttcn @@ -47,12 +47,26 @@ /* 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 */ @@ -223,6 +237,19 @@ } }; + 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 @@ /* 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 @@ /* 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/NS_Emulation.ttcn b/library/NS_Emulation.ttcn index 27acae2..df9a7b0 100644 --- a/library/NS_Emulation.ttcn +++ b/library/NS_Emulation.ttcn @@ -84,7 +84,7 @@ g_conn_id := res.connId; f_change_state(NSE_S_DEAD_BLOCKED); /* Send the first NS-ALIVE to test the connection */ - f_sendReset(); + //f_sendReset(); } type component NS_CT { diff --git a/library/Osmocom_Gb_Types.ttcn b/library/Osmocom_Gb_Types.ttcn index f943c9c..3de7427 100644 --- a/library/Osmocom_Gb_Types.ttcn +++ b/library/Osmocom_Gb_Types.ttcn @@ -301,8 +301,8 @@ } 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 2335c29..95b5838 100644 --- a/library/RLCMAC_CSN1_Types.ttcn +++ b/library/RLCMAC_CSN1_Types.ttcn @@ -513,4 +513,16 @@ 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 a30a43c..937aa7b 100644 --- a/library/RLCMAC_Types.ttcn +++ b/library/RLCMAC_Types.ttcn @@ -226,4 +226,17 @@ 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)" } -- To view, visit https://gerrit.osmocom.org/7152 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I2c7d0eb9371911e28f328caeaed63cb8ec311ac1 Gerrit-PatchSet: 1 Gerrit-Project: osmo-ttcn3-hacks Gerrit-Branch: master Gerrit-Owner: Harald Welte <lafo...@gnumonks.org>