gprs_gb: working Uplink PACKET_CONTROL_ACK against OsmoPCU
Change-Id: I2c7d0eb9371911e28f328caeaed63cb8ec311ac1
This commit is contained in:
parent
fd445c34fe
commit
7024baa66c
|
@ -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]
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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" };
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)" };
|
||||
|
|
|
@ -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)" }
|
||||
|
|
Loading…
Reference in New Issue