BSSGP_Emulation: Support multiple PTP-BVC within one Entity

The existing BSSGP_Emulation is built around the assumption that every
instance of BSSGP_Emulation only servers one signaling-BVC and one
PTP-BVC.  While this is true for osmo-pcu at this point (BTS-colocated
PCU), other BSS/PCU implementations differ.

In general, there can always be any number of PTP BVC (one per cell)
next to the signaling BVC (one per BSS).  Let's represent this in
BSSGP_Emulation so we can create more comprehensive tests.

Change-Id: I7e30b4c4e188518a574e082962fba457b3a97ce3
This commit is contained in:
Harald Welte 2020-10-04 22:52:56 +02:00
parent 23e274919d
commit 5339b2e372
8 changed files with 1210 additions and 706 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1555,6 +1555,74 @@ octetstring sdu) := {
}
/* extract the BVCI IE of given PDU + return it */
function f_BSSGP_BVCI_IE_get(PDU_BSSGP pdu) return template (omit) BVCI {
select (pdu) {
case (PDU_BSSGP:{pDU_BSSGP_FLUSH_LL:=?}) {
return pdu.pDU_BSSGP_FLUSH_LL.bVCI_old;
}
case (PDU_BSSGP:{pDU_BSSGP_FLUSH_LL_ACK:=?}) {
return pdu.pDU_BSSGP_FLUSH_LL_ACK.bVCI_new;
}
case (PDU_BSSGP:{pDU_BSSGP_LLC_DISCARDED:=?}) {
return pdu.pDU_BSSGP_LLC_DISCARDED.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_BVC_BLOCK:=?}) {
return pdu.pDU_BSSGP_BVC_BLOCK.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_BVC_BLOCK_ACK:=?}) {
return pdu.pDU_BSSGP_BVC_BLOCK_ACK.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_BVC_UNBLOCK:=?}) {
return pdu.pDU_BSSGP_BVC_UNBLOCK.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_BVC_UNBLOCK_ACK:=?}) {
return pdu.pDU_BSSGP_BVC_UNBLOCK_ACK.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_BVC_RESET:=?}) {
return pdu.pDU_BSSGP_BVC_RESET.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_BVC_RESET_ACK:=?}) {
return pdu.pDU_BSSGP_BVC_RESET_ACK.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_STATUS:=?}) {
return pdu.pDU_BSSGP_STATUS.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_PERFORM_LOCATION_REQUEST:=?}) {
return pdu.pDU_BSSGP_PERFORM_LOCATION_REQUEST.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_PERFORM_LOCATION_RESPONSE:=?}) {
return pdu.pDU_BSSGP_PERFORM_LOCATION_RESPONSE.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_PERFORM_LOCATION_ABORT:=?}) {
return pdu.pDU_BSSGP_PERFORM_LOCATION_ABORT.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_POSITION_COMMAND:=?}) {
return pdu.pDU_BSSGP_POSITION_COMMAND.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_POSITION_RESPONSE:=?}) {
return pdu.pDU_BSSGP_POSITION_RESPONSE.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_PAGING_PS:={?,?,*,{bVCI:=?},*,*,?,*,*}}) {
return pdu.pDU_BSSGP_PAGING_PS.paging_Field4.bVCI;
}
case (PDU_BSSGP:{pDU_BSSGP_PAGING_CS:={?,?,?,{bVCI:=?},*,*,*,*,*}}) {
return pdu.pDU_BSSGP_PAGING_CS.paging_Field4.bVCI;
}
case else {
return omit;
}
}
}
/* extract the BVCI IE of given PDU + convert it to integer value */
function f_BSSGP_BVCI_get(PDU_BSSGP pdu) return template (omit) BssgpBvci {
var template (omit) BVCI bvci_raw := f_BSSGP_BVCI_IE_get(pdu);
if (istemplatekind(bvci_raw, "omit")) {
return omit;
}
return oct2int(valueof(bvci_raw.unstructured_value));
}
} with { encode "RAW" };

View File

@ -10,18 +10,23 @@ ConsoleMask := ERROR | WARNING | TESTCASE | TIMEROP_START | DEBUG_ENCDEC | USER
[MODULE_PARAMETERS]
SGSN_Components.mp_gb_cfg := {
nsei := 1234,
bvci := 1234,
cell_id := {
ra_id := {
lai := {
mcc_mnc := '262F42'H, lac := 13135
sgsn_role := true,
bvc := {
{
bvci := 1234,
cell_id := {
ra_id := {
lai := {
mcc_mnc := '262F42'H, lac := 13135
},
rac := 0
},
cell_id := 20960
},
rac := 0
},
cell_id := 20960
},
sgsn_role := true
}
depth := BSSGP_DECODE_DEPTH_BSSGP
}
}
};
Osmocom_VTY_Functions.mp_prompt_prefix := "OsmoPCU";
PCUIF_Types.mp_pcuif_version := 10;
StatsD_Checker.mp_enable_stats := true;

View File

@ -83,7 +83,7 @@ friend template (value) PCUIF_info_ind ts_PCUIF_INFO_default := {
cell_id := 20960,
repeat_time := 5 * 50,
repeat_count := 3,
bvci := mp_gb_cfg.bvci,
bvci := mp_gb_cfg.bvc[0].bvci,
t3142 := 20,
t3169 := 5,
t3191 := 5,
@ -215,12 +215,12 @@ runs on RAW_PCU_Test_CT {
activate(as_Tguard_RAW());
/* Init PCU interface component */
vc_PCUIF := RAW_PCUIF_CT.create("PCUIF-" & id);
vc_PCUIF := RAW_PCUIF_CT.create("PCUIF");
connect(vc_PCUIF:MTC, self:PCUIF);
map(vc_PCUIF:PCU, system:PCU);
/* Create one BTS component (we may want more some day) */
vc_BTS := RAW_PCU_BTS_CT.create("BTS-" & id);
vc_BTS := RAW_PCU_BTS_CT.create("BTS");
connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
connect(vc_BTS:TC, self:BTS);
@ -239,7 +239,7 @@ runs on RAW_PCU_Test_CT {
}
testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.cell_id.ra_id);
var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
var GprsTlli tlli := 'FFFFFFFF'O;
timer T;
@ -256,7 +256,7 @@ testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
T.start(2.0);
alt {
[] BSSGP_SIG[0].receive(tr_BSSGP_SUSPEND(tlli, mp_gb_cfg.cell_id.ra_id)) {
[] BSSGP_SIG[0].receive(tr_BSSGP_SUSPEND(tlli, mp_gb_cfg.bvc[0].cell_id.ra_id)) {
setverdict(pass);
}
[] T.timeout {
@ -890,7 +890,7 @@ testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
/* receive one message on BSSGP with all aggregated data in payload: */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, total_payload));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, total_payload));
}
/* Verify PCU handles correctly CS1..4 with all possible LLC payload sizes fitting alone in one RLC block */
@ -936,7 +936,7 @@ testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT {
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
/* receive one message on BSSGP with all aggregated data in payload: */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, payload));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, payload));
/* Test sending LLC PDUS of incrementing size */
var integer max_size := 49;
@ -962,7 +962,7 @@ testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT {
f_ms_tx_ul_block(ms, ul_data);
/* receive one message on BSSGP with all aggregated data in payload: */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, payload));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, payload));
/* we will receive UL ACK/NACK from time to time, handle it. */
f_rx_rlcmac_dl_block(dl_block, dl_fn);
@ -1007,7 +1007,7 @@ function f_TC_ul_data_toolong_fills_padding_cs(inout GprsMS ms, CodingScheme cs,
T.start(0.5);
alt {
[] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, ?)) {
[] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, ?)) {
setverdict(fail, "LLC PDU in Malformed RLC block was forwarded");
f_shutdown(__BFILE__, __LINE__);
}
@ -1082,7 +1082,7 @@ private function f_TC_mo_ping_pong_1phase_access(template (present) CodingScheme
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
/* UL block should be received in SGSN */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
/* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
@ -1172,7 +1172,7 @@ runs on RAW_PCU_Test_CT {
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
/* UL block should be received in SGSN */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
/* Now SGSN sends some DL data, PCU will page on PACCH */
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
@ -1287,7 +1287,7 @@ private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSG
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
/* UL block should be received in SGSN */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
f_shutdown(__BFILE__, __LINE__, final := true);
}
@ -1383,7 +1383,7 @@ testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
/* receive one message on BSSGP with all aggregated data in payload: */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, total_payload));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, total_payload));
}
/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
@ -1581,7 +1581,7 @@ testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
f_ms_tx_ul_block(ms, ul_data);
/* UL block dataA should be received in SGSN */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, dataA));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataA));
/* UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1] */
ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
@ -1598,8 +1598,8 @@ testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
f_ms_tx_ul_block(ms, ul_data);
/* UL block dataB and dataC should be received in SGSN */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, dataB));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, dataC));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataB));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataC));
/* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
@ -1613,7 +1613,7 @@ testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
f_ms_tx_ul_block(ms, ul_data);
/* UL block dataB and dataD should be received in SGSN */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, dataD));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataD));
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
@ -1656,7 +1656,7 @@ testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT {
f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
/* UL block should be received in SGSN */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
tr_UlAckNackGprs(ms.tlli,
@ -1677,7 +1677,7 @@ testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT {
f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := false); /* TODO: send using cs_mcs */
/* UL block should be received in SGSN */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
/* ACK the ACK */
@ -1811,7 +1811,7 @@ testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
}
testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvci);
f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvc[0].bvci);
}
/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
@ -1858,7 +1858,7 @@ testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
}
testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvci);
f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
}
/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
@ -1894,7 +1894,7 @@ testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
/* UL block should be received in SGSN */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
/* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
@ -1953,7 +1953,7 @@ testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
/* UL block should be received in SGSN */
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
/* Now SGSN sends some DL data with an invalid IMSI */
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));

View File

@ -55,7 +55,7 @@ function f_init_pcuif() runs on RAW_PCU_CT {
/* Wait for PCU_VERSION and return INFO_IND */
PCU.receive(t_SD_PCUIF(g_pcu_conn_id, tr_PCUIF_TXT_IND(0, PCU_VERSION, ?)));
/* FIXME: make sure to use parameters from mp_gb_cfg.cell_id in the PCU INFO IND */
/* FIXME: make sure to use parameters from mp_gb_cfg.bvc[0].cell_id in the PCU INFO IND */
var template PCUIF_Message info_ind_msg := ts_PCUIF_INFO_IND(0, info_ind);
PCU.send(t_SD_PCUIF(g_pcu_conn_id, info_ind_msg));
}
@ -194,16 +194,16 @@ testcase TC_ns_full_bringup() runs on RAW_Test_CT {
/* Expect BVC-RESET for signaling (0) and ptp BVCI */
if (mp_tolerate_bvc_reset_cellid) {
as_rx_bvc_reset_tx_ack(0, mp_gb_cfg.cell_id, oneshot := true);
as_rx_bvc_reset_tx_ack(0, mp_gb_cfg.bvc[0].cell_id, oneshot := true);
} else {
as_rx_bvc_reset_tx_ack(0, omit, oneshot := true);
}
as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvci, mp_gb_cfg.cell_id, oneshot := true);
as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvci, oneshot := true);
as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, oneshot := true);
as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true);
/* wait for one FLOW-CONTROL BVC and then ACK any further in the future */
as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, oneshot := true);
activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci));
as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true);
activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci));
setverdict(pass);
}

View File

@ -187,13 +187,13 @@ testcase TC_sns_so_config_success() runs on RAW_Test_CT {
f_outgoing_ns_alive();
/* Expect BVC-RESET for signaling (0) and ptp BVCI */
as_rx_bvc_reset_tx_ack(0, mp_gb_cfg.cell_id, oneshot := true);
as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvci, mp_gb_cfg.cell_id, oneshot := true);
as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvci, oneshot := true);
as_rx_bvc_reset_tx_ack(0, mp_gb_cfg.bvc[0].cell_id, oneshot := true);
as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, oneshot := true);
as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true);
/* wait for one FLOW-CONTROL BVC and then ACK any further in the future */
as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, oneshot := true);
activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci));
as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true);
activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci));
setverdict(pass);
}
@ -220,20 +220,20 @@ private function f_sns_bringup_1c1u(boolean sgsn_originated_reset := false) runs
f_outgoing_ns_alive(1);
if (sgsn_originated_reset) {
f_tx_bvc_reset_rx_ack(0, mp_gb_cfg.cell_id);
f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvci, mp_gb_cfg.cell_id);
f_tx_bvc_reset_rx_ack(0, mp_gb_cfg.bvc[0].cell_id);
f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id);
} else {
/* Expect BVC-RESET for signaling (0) and ptp BVCI */
as_rx_bvc_reset_tx_ack(0, mp_gb_cfg.cell_id, oneshot := true);
as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvci, mp_gb_cfg.cell_id, oneshot := true);
as_rx_bvc_reset_tx_ack(0, mp_gb_cfg.bvc[0].cell_id, oneshot := true);
as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, oneshot := true);
}
/* Expect UNBLOCK for ptp BVCI on signaling NS-VC (idx==0) */
as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvci, oneshot := true);
as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true);
/* wait for one FLOW-CONTROL BVC and then ACK any further in the future. Flow
* control happens on the p-t-p BVCI and hence on index 1 */
as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, oneshot := true, idx := 1);
activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, idx := 1));
as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true, idx := 1);
activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci, idx := 1));
}
/* Test full IP-SNS bring-up with two NS-VCs, one sig-only and one user-only */
@ -270,20 +270,20 @@ private function f_sns_bringup_1c1u_separate(boolean sgsn_originated_reset := fa
f_outgoing_ns_alive_no_ack(idx := 0);
if (sgsn_originated_reset) {
f_tx_bvc_reset_rx_ack(0, mp_gb_cfg.cell_id, idx := 1);
f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvci, mp_gb_cfg.cell_id, idx := 1);
f_tx_bvc_reset_rx_ack(0, mp_gb_cfg.bvc[0].cell_id, idx := 1);
f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, idx := 1);
} else {
/* Expect BVC-RESET for signaling BVCI=0 and ptp BVCI */
as_rx_bvc_reset_tx_ack(0, mp_gb_cfg.cell_id, oneshot := true, idx := 1);
as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvci, mp_gb_cfg.cell_id, oneshot := true, idx := 1);
as_rx_bvc_reset_tx_ack(0, mp_gb_cfg.bvc[0].cell_id, oneshot := true, idx := 1);
as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, oneshot := true, idx := 1);
}
/* Expect UNBLOCK for ptp BVCI on signaling NS-VC (idx==1) */
as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvci, oneshot := true, idx := 1);
as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true, idx := 1);
/* wait for one FLOW-CONTROL BVC and then ACK any further in the future. Flow
* control happens on the p-t-p BVCI and hence on index 1 */
as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, oneshot := true, idx := 2);
activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, idx := 2));
as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true, idx := 2);
activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci, idx := 2));
}
/* Test full IP-SNS bring-up with two NS-VCs, one sig-only and one user-only - and where
@ -322,8 +322,8 @@ testcase TC_sns_1c1u_so_bvc_reset_too_early() runs on RAW_Test_CT {
f_outgoing_ns_alive_no_ack(idx := 0);
/* Transmit BVC-RESET and expect no ACK*/
f_tx_bvc_reset_rx_ack(0, mp_gb_cfg.cell_id, idx := 1, exp_ack := false);
f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvci, mp_gb_cfg.cell_id, idx := 1, exp_ack := false);
f_tx_bvc_reset_rx_ack(0, mp_gb_cfg.bvc[0].cell_id, idx := 1, exp_ack := false);
f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, idx := 1, exp_ack := false);
}
/* Test adding new IP endpoints at runtime */

View File

@ -20,18 +20,22 @@ import from GPRS_Context all;
modulepar {
BssgpConfig mp_gb_cfg := {
nsei := 1234,
bvci := 1234,
cell_id := {
ra_id := {
lai := {
mcc_mnc := '262F42'H, lac := 13135
},
rac := 0
},
cell_id := 20960
},
sgsn_role := true,
depth := BSSGP_DECODE_DEPTH_BSSGP
bvc := {
{
bvci := 1234,
cell_id := {
ra_id := {
lai := {
mcc_mnc := '262F42'H, lac := 13135
},
rac := 0
},
cell_id := 20960
},
depth := BSSGP_DECODE_DEPTH_BSSGP
}
}
};
NSConfiguration mp_nsconfig := {
@ -55,6 +59,7 @@ modulepar {
type component bssgp_CT extends BSSGP_Client_CT {
var NS_CT ns_component;
var BSSGP_CT bssgp_component;
port BSSGP_CT_PROC_PT PROC;
var boolean g_initialized := false;
}
@ -75,16 +80,22 @@ function f_init_bssgp() runs on bssgp_CT {
/* create a new NS component */
ns_component := NS_CT.create;
bssgp_component := BSSGP_CT.create;
/* connect our BSSGP port to the BSSGP Emulation */
connect(self:BSSGP[0], bssgp_component:BSSGP_SP);
connect(self:BSSGP_SIG[0], bssgp_component:BSSGP_SP_SIG);
connect(self:BSSGP_PROC[0], 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(self:PROC, bssgp_component:PROC);
ns_component.start(NSStart(mp_nsconfig));
bssgp_component.start(BssgpStart(mp_gb_cfg));
bssgp_component.start(BssgpStart(mp_gb_cfg, testcasename()));
f_bssgp_client_register(mmctx.imsi, mmctx.tlli, mp_gb_cfg.cell_id);
for (var integer i := 0; i < lengthof(mp_gb_cfg.bvc); i := i+1) {
var BSSGP_BVC_CT vc_BVC;
/* obtain reference for BVC component (created by BssgpStart) */
vc_BVC := f_bssgp_get_bvci_ct(mp_gb_cfg.bvc[i].bvci, PROC);
/* connect our BSSGP port to the BSSGP Emulation */
connect(self:BSSGP[i], vc_BVC:BSSGP_SP);
connect(self:BSSGP_SIG[i], vc_BVC:BSSGP_SP_SIG);
connect(self:BSSGP_PROC[i], vc_BVC:BSSGP_PROC);
f_bssgp_client_register(mmctx.imsi, mmctx.tlli);
}
}
/* Establish BSSGP connection to PCU */
@ -93,7 +104,7 @@ function f_bssgp_establish() runs on BSSGP_Client_CT {
T.start
alt {
[] BSSGP[0].receive(t_BssgpStsInd(?, ?, BVC_S_UNBLOCKED)) { }
[] BSSGP[0].receive(tr_BssgpStsInd(*, ?, BVC_S_UNBLOCKED)) { }
[] BSSGP[0].receive { repeat; }
[] T.timeout {
setverdict(fail, "Timeout establishing BSSGP connection");

View File

@ -130,9 +130,11 @@ modulepar {
}
};
const integer NUM_BVC_PER_NSE := 1;
type record GbInstance {
NS_CT vc_NS,
BSSGP_CT vc_BSSGP,
BSSGP_BVC_CT vc_BSSGP_BVC[NUM_BVC_PER_NSE],
BssgpConfig cfg
};
@ -154,6 +156,9 @@ type component test_CT {
/* only to get events from IPA underneath GSUP */
port IPA_CTRL_PT GSUP_IPA_EVENT;
/* only needed at start to get the per-BVC references */
port BSSGP_CT_PROC_PT PROC;
var GTP_Emulation_CT vc_GTP;
port TELNETasp_PT SGSNVTY;
@ -223,7 +228,13 @@ private function f_init_gb(inout GbInstance gb, charstring id, integer offset) r
connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
gb.vc_BSSGP.start(BssgpStart(gb.cfg));
gb.vc_BSSGP.start(BssgpStart(gb.cfg, testcasename()));
/* resolve the per-BVC component references */
for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i+1) {
connect(self:PROC, gb.vc_BSSGP:PROC);
gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
disconnect(self:PROC, gb.vc_BSSGP:PROC);
}
}
private function f_init_gsup(charstring id) runs on test_CT {
@ -297,45 +308,63 @@ function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
g_initialized := true;
g_gb[0].cfg := {
nsei := 96,
bvci := 196,
cell_id := {
ra_id := {
lai := {
mcc_mnc := mcc_mnc, lac := 13135},
rac := 0
},
cell_id := 20960
},
sgsn_role := false,
depth := BSSGP_DECODE_DEPTH_L3
bvc := {
{
bvci := 196,
cell_id := {
ra_id := {
lai := {
mcc_mnc := mcc_mnc,
lac := 13135
},
rac := 0
},
cell_id := 20960
},
depth := BSSGP_DECODE_DEPTH_L3
}
}
};
g_gb[1].cfg := {
nsei := 97,
bvci := 210,
cell_id := {
ra_id := {
lai := {
mcc_mnc := mcc_mnc, lac := 13200},
rac := 0
},
cell_id := 20961
},
sgsn_role := false,
depth := BSSGP_DECODE_DEPTH_L3
bvc := {
{
bvci := 210,
cell_id := {
ra_id := {
lai := {
mcc_mnc := mcc_mnc,
lac := 13200
},
rac := 0
},
cell_id := 20961
},
depth := BSSGP_DECODE_DEPTH_L3
}
}
};
g_gb[2].cfg := {
nsei := 98,
bvci := 220,
cell_id := {
ra_id := {
lai := {
mcc_mnc := mcc_mnc, lac := 13300},
rac := 0
},
cell_id := 20962
},
sgsn_role := false,
depth := BSSGP_DECODE_DEPTH_L3
bvc := {
{
bvci := 220,
cell_id := {
ra_id := {
lai := {
mcc_mnc := mcc_mnc,
lac := 13300
},
rac := 0
},
cell_id := 20962
},
depth := BSSGP_DECODE_DEPTH_L3
}
}
};
f_init_vty();
@ -413,7 +442,11 @@ runs on test_CT return BSSGP_ConnHdlr {
tlli := f_gprs_tlli_random(),
tlli_old := omit,
ra := omit,
bssgp_cell_id := { gb[0].cfg.cell_id, gb[1].cfg.cell_id, gb[2].cfg.cell_id },
bssgp_cell_id := {
gb[0].cfg.bvc[0].cell_id,
gb[1].cfg.bvc[0].cell_id,
gb[2].cfg.bvc[0].cell_id
},
rnc_send_initial_ue := true,
vec := omit,
net := net_pars,
@ -428,15 +461,18 @@ runs on test_CT return BSSGP_ConnHdlr {
}
vc_conn := BSSGP_ConnHdlr.create(id);
connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP:BSSGP_SP_SIG);
connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP:BSSGP_SP_SIG);
connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP:BSSGP_SP_SIG);
connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP);
connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_PROC);
connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP);
connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_PROC);
connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP);
connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_PROC);
/* FIXME: support multiple RNCs */
if (g_ranap_enable) {
@ -470,7 +506,7 @@ runs on BSSGP_ConnHdlr {
llc := f_llc_create(false);
/* register with BSSGP core */
f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
/* tell GSUP dispatcher to send this IMSI to us */
f_create_gsup_expect(hex2str(g_pars.imsi));
/* tell GTP dispatcher to send this IMSI to us */
@ -1091,7 +1127,7 @@ private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdl
/* Simulate a foreign IMSI */
g_pars.imsi := '001010123456789'H;
f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
g_pars.net.expect_auth := false;
@ -2344,7 +2380,7 @@ private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_Conn
f_bssgp_client_unregister(g_pars.imsi);
/* Simulate a foreign IMSI */
g_pars.imsi := '001010123456700'H;
f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
/* there is no auth */
g_pars.net.expect_auth := false;
@ -2522,7 +2558,7 @@ private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
log("rau complete unregistering");
f_bssgp_client_unregister(g_pars.imsi);
f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
log("sending second RAU via different RA");
f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);