bts: Test forwarding PCUIF<->IPA/OSMO/PCU

Change-Id: I78880098a55d1cb456011746efa0a47832a86ca8
This commit is contained in:
Pau Espin 2021-06-25 13:55:38 +02:00
parent 6c864ec07a
commit 65d712e973
5 changed files with 195 additions and 6 deletions

View File

@ -31,6 +31,7 @@ BTS_Tests.mp_pcu_socket := "/tmp/pcu_sock"
#BTS_Tests.mp_tolerance_rxlev := 10;
#BTS_Tests.mp_tolerance_rxqual := 1;
BTS_Tests_OML.mp_pcu_socket := "/tmp/pcu_sock"
[MAIN_CONTROLLER]

View File

@ -70,6 +70,7 @@ friend module BTS_Tests_VAMOS;
friend module BTS_Tests_virtphy;
friend module BTS_Tests_LAPDm;
friend module BTS_Tests_perf;
friend module BTS_Tests_OML;
/* The tests assume a BTS with the following timeslot configuration:
* TS0 : Combined CCCH + SDCCH/4
@ -440,7 +441,7 @@ friend function f_connhdlr_init_vty_bsc() runs on ConnHdlr {
}
/* PCU socket may at any time receive a new INFO.ind */
private altstep as_pcu_info_ind(PCUIF_CODEC_PT pt, integer pcu_conn_id,
friend altstep as_pcu_info_ind(PCUIF_CODEC_PT pt, integer pcu_conn_id,
out PCUIF_Message pcu_last_info) {
var PCUIF_send_data sd;
[] pt.receive(t_SD_PCUIF(pcu_conn_id, tr_PCUIF_INFO_IND(0, ?))) -> value sd {

View File

@ -16,6 +16,13 @@ import from Osmocom_Types all;
import from AbisOML_Types all;
import from IPA_Emulation all;
import from IPA_Types all;
import from Misc_Helpers all;
import from PCUIF_Types all;
import from PCUIF_CodecPort all;
import from PCUIF_CodecPort all;
import from BTS_Tests all;
const integer NUM_TRX := 8;
@ -43,6 +50,8 @@ modulepar {
uint8_t mp_air_timer := 100;
uint8_t mp_ny1 := 10;
uint8_t mp_bsic := 63;
charstring mp_pcu_socket := PCU_SOCK_DEFAULT;
};
/* BSC side OML component */
@ -52,8 +61,17 @@ type component BSC_OML_CT {
/* Port for OML */
port IPA_OML_PT OML;
var uint8_t g_bts_nr := 0;
/* Port for Abis/Osmo/PCU */
port IPA_OSMO_PCU_PT IPA_OSMO_PCU;
/* PCU Interface of BTS */
port PCUIF_CODEC_PT PCU;
var integer g_pcu_conn_id;
/* Last PCU INFO IND we received */
var PCUIF_Message g_pcu_last_info;
/* As rxed by Get Attributes Response NM_ATT_MANUF_ID IE, see f_oml_getattr() */
var bitstring g_bts_features;
/* global test case guard timer */
timer T_oml_guard := 60.0;
@ -112,6 +130,27 @@ function f_init_oml(charstring id) runs on BSC_OML_CT {
activate(as_IPA_evt());
}
private function f_init_pcu(PCUIF_CODEC_PT pt, charstring id,
out integer pcu_conn_id, out PCUIF_Message pcu_last_info) {
timer T := 2.0;
var PCUIF_send_data sd;
if (mp_pcu_socket == "") {
pcu_conn_id := -1;
return;
}
map(self:PCU, system:PCU);
pcu_conn_id := f_pcuif_connect(pt, mp_pcu_socket);
T.start;
alt {
[] as_pcu_info_ind(pt, pcu_conn_id, pcu_last_info);
[] T.timeout {
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for PCU INFO_IND");
}
}
pt.send(t_SD_PCUIF(pcu_conn_id, ts_PCUIF_TXT_IND(0, PCU_VERSION, testcasename())));
}
/* Perform an "OPSTART" procedure with the speciifed MO" */
private function f_oml_opstart(template (value) OML_FOM_ObjectClass obj_class,
@ -290,12 +329,15 @@ private function f_oml_send_exp_no_resp(template (value) OML_PDU tx, charstring
}
}
private function f_oml_exp_rx(template OML_PDU exp_rx, charstring err_msg) runs on BSC_OML_CT
private function f_oml_exp_rx(template OML_PDU exp_rx, charstring err_msg)
runs on BSC_OML_CT return OML_PDU
{
var OML_PDU rx;
timer T := 5.0;
T.start;
alt {
[] OML.receive(exp_rx) {
[] OML.receive(exp_rx) -> value rx {
setverdict(pass);
}
[] OML.receive { repeat; }
@ -303,6 +345,7 @@ private function f_oml_exp_rx(template OML_PDU exp_rx, charstring err_msg) runs
setverdict(fail, "Timeout waiting for ", err_msg);
}
}
return rx;
}
/* Send an OML message and expect a failure event report in response */
@ -351,7 +394,23 @@ private function f_oml_send_exp_nack(template (value) OML_PDU tx, template OML_F
}
private function f_oml_getattr(template OML_PDU exp_rx := tr_OML_GetAttributesResponse(NM_OC_BTS, ?, ?)) runs on BSC_OML_CT
{
var OML_FOM_ObjectInstance obj_inst := valueof(ts_OML_ObjectInstance(g_bts_nr, 255, 255));
var OML_FOM_IE_Type attr_li[2] := { NM_ATT_MANUF_ID, NM_ATT_SW_CONFIG };
var octetstring req_attr := ''O;
for (var integer i := 0; i < lengthof(attr_li); i := i + 1) {
req_attr := req_attr & int2oct(enum2int(attr_li[i]), 1);
}
var OML_PDU cmd := valueof(ts_OML_GetAttributes(NM_OC_BTS, obj_inst, req_attr));
OML.send(cmd);
var OML_PDU rx := f_oml_exp_rx(exp_rx, "BTS GetAttributes Response");
var OML_FOM_IE_Body ie_ari := f_OML_FOM_get_ie(rx.u.fom, NM_ATT_GET_ARI);
var OML_FOM_IE_Body manuf_id := f_OML_FOM_IE_List_get_ie(ie_ari.ari.ies, NM_ATT_MANUF_ID);
g_bts_features := oct2bit(manuf_id.other.payload);
}
@ -616,6 +675,57 @@ testcase TC_ipa_rsl_connect_nack() runs on BSC_OML_CT {
}
}
/* Make sure that the IUT forwards Container PCUIF messages between BSC and PCU */
testcase TC_ipa_osmo_pcu_anr_fwd() runs on BSC_OML_CT {
var PCUIF_send_data pcu_sd_msg;
var PCUIF_Message msg_rx;
timer T := 2.0;
var octetstring payloadReq := f_rnd_octstring(300);
var octetstring payloadRep := f_rnd_octstring(300);
f_init_oml(testcasename());
f_init_pcu(PCU, testcasename(), g_pcu_conn_id, g_pcu_last_info);
f_oml_getattr();
log("BTS Features:", g_bts_features);
if (lengthof(g_bts_features) < 21 or g_bts_features[20] != '1'B) {
setverdict(fail, "Feature ABIS_OSMO_PCU not supported!");
}
IPA_OSMO_PCU.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP));
IPA_OSMO_PCU.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_RESP));
IPA_OSMO_PCU.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK));
IPA_OSMO_PCU.send(ts_PCUIF_CONTAINER(0, ts_PCUIF_CONT_OTHER(100, payloadReq)))
T.start;
alt {
[] PCU.receive(t_SD_PCUIF(g_pcu_conn_id, tr_PCUIF_CONTAINER(0, tr_PCUIF_CONT_OTHER(100, payloadReq)))) {
setverdict(pass);
}
[] PCU.receive(PCUIF_send_data:?) -> value pcu_sd_msg {
setverdict(fail, "Unexpected message received: ", pcu_sd_msg.data, " vs exp: ",
t_SD_PCUIF(g_pcu_conn_id, tr_PCUIF_CONTAINER(0, tr_PCUIF_CONT_OTHER(100, payloadReq))));
}
[] T.timeout { setverdict(fail, "Timeout waiting for ANR request on PCU inteface");}
}
T.stop;
/* Send back the response: */
PCU.send(t_SD_PCUIF(g_pcu_conn_id, ts_PCUIF_CONTAINER(0, ts_PCUIF_CONT_OTHER(100, payloadRep))))
T.start;
alt {
[] IPA_OSMO_PCU.receive(tr_PCUIF_CONTAINER(0, tr_PCUIF_CONT_OTHER(100, payloadRep))) {
setverdict(pass);
}
[] IPA_OSMO_PCU.receive(PCUIF_Message:?) -> value msg_rx {
setverdict(fail, "Unexpected message received: ", msg_rx, " vs exp: ",
tr_PCUIF_CONTAINER(0, tr_PCUIF_CONT_OTHER(100, payloadRep)));
}
[] T.timeout { setverdict(fail, "Timeout waiting for ANR request on BSC inteface"); }
}
setverdict(pass);
}
control {
execute( TC_wrong_mdisc() );
@ -634,6 +744,8 @@ control {
execute( TC_ts_opstart_noattr() );
execute( TC_initial_state_reports() );
execute( TC_ipa_rsl_connect_nack() );
execute( TC_ipa_osmo_pcu_anr_fwd() );
}
/* BTS:

View File

@ -1226,6 +1226,21 @@ function f_OML_make_nack_exp(OML_PDU orig, template OML_FOM_NackCause cause) ret
return resp;
}
function f_OML_FOM_IE_List_get_ie(OML_FOM_IE_List ie_list, OML_FOM_IE_Type iei) return OML_FOM_IE_Body
{
for (var integer i := 0; i < lengthof(ie_list); i := i + 1) {
if (ie_list[i].iei == iei) {
return ie_list[i].body;
}
}
var OML_FOM_IE_Body dummy;
return dummy; /*TODO: setverdict(fail?) */
}
function f_OML_FOM_get_ie(OML_FOM fom, OML_FOM_IE_Type iei) return OML_FOM_IE_Body
{
return f_OML_FOM_IE_List_get_ie(fom.ies, iei);
}
/***********************************************************************

View File

@ -37,7 +37,8 @@ type enumerated PCUIF_MsgType {
PCU_IF_MSG_TIME_IND ('52'O),
PCU_IF_MSG_INTERF_IND ('53'O),
PCU_IF_MSG_PAG_REQ ('60'O),
PCU_IF_MSG_TXT_IND ('70'O)
PCU_IF_MSG_TXT_IND ('70'O),
PCU_IF_MSG_CONTAINER ('80'O)
} with { variant "FIELDLENGTH(8)" };
type enumerated PCUIF_Sapi {
@ -253,6 +254,26 @@ type record PCUIF_susp_req {
variant (tlli) "BYTEORDER(last)"
};
type union PCUIF_ContainerMsgUnion {
/* This field can be removed once first container message is added, see
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=574469 */
octetstring tmp_fixme,
octetstring other
} with { variant "" };
type record PCUIF_container {
uint8_t msg_type,
OCT1 spare,
uint16_t len, /* network byte order */
PCUIF_ContainerMsgUnion u
} with {
variant (len) "BYTEORDER(last)"
variant (len) "LENGTHTO(u)"
variant (u) "CROSSTAG(
tmp_fixme, msg_type = 255;
other, OTHERWISE)"
};
type union PCUIF_MsgUnion {
PCUIF_data data_req,
@ -268,7 +289,8 @@ type union PCUIF_MsgUnion {
PCUIF_time_ind time_ind,
PCUIF_interf_ind interf_ind,
PCUIF_pag_req pag_req,
PCUIF_app_info_req app_info_req
PCUIF_app_info_req app_info_req,
PCUIF_container container
} with { variant "" };
type record PCUIF_Message {
@ -290,7 +312,8 @@ type record PCUIF_Message {
time_ind, msg_type = PCU_IF_MSG_TIME_IND;
interf_ind, msg_type = PCU_IF_MSG_INTERF_IND;
pag_req, msg_type = PCU_IF_MSG_PAG_REQ;
app_info_req, msg_type = PCU_IF_MSG_APP_INFO_REQ)"
app_info_req, msg_type = PCU_IF_MSG_APP_INFO_REQ;
container, msg_type = PCU_IF_MSG_CONTAINER)"
/* PCUIFv10: 1006 * 8 = 8048 bits */
variant "PADDING(8048)"
};
@ -984,6 +1007,43 @@ template (present) PCUIF_Message tr_PCUIF_APP_INFO_REQ(template (present) uint8_
}
template (value) PCUIF_Message ts_PCUIF_CONTAINER(template (value) uint8_t bts_nr,
template (value) PCUIF_container container) := {
msg_type := PCU_IF_MSG_CONTAINER,
bts_nr := bts_nr,
spare := '0000'O,
u := {
container := container
}
}
template (present) PCUIF_Message tr_PCUIF_CONTAINER(template (present) uint8_t bts_nr,
template (present) PCUIF_container container) := {
msg_type := PCU_IF_MSG_CONTAINER,
bts_nr := bts_nr,
spare := '0000'O,
u := {
container := container
}
}
template (value) PCUIF_container ts_PCUIF_CONT_OTHER(uint8_t msg_type, template (value) octetstring payload) := {
msg_type := msg_type,
spare := '00'O,
len := lengthof(payload),
u := {
other := payload
}
}
template (present) PCUIF_container tr_PCUIF_CONT_OTHER(template (present) uint8_t msg_type,
template (present) octetstring payload) := {
msg_type := msg_type,
spare := '00'O,
len := ?,
u := {
other := payload
}
}
function f_PCUIF_PDCHMask_set(inout PCUIF_info_ind info, BIT8 pdch_mask,
template (present) uint8_t trx_nr := ?)
{