osmo-ttcn3-hacks/library/PCUIF_Types.ttcn

1186 lines
28 KiB
Plaintext
Raw Normal View History

/* Osmocom PCU Interface Types, as per osmo-pcu/include/osmocom/pcu/pcuif_proto.h
* (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
* contributions by Vadim Yanitskiy <axilirator@gmail.com>
* All rights reserved.
*
* Released under the terms of GNU General Public License, Version 2 or
* (at your option) any later version.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
module PCUIF_Types {
import from General_Types all;
import from Osmocom_Types all;
import from Native_Functions all;
modulepar {
/* PCUIF version supported by the IUT */
PCUIF_Version mp_pcuif_version := 10;
};
const charstring PCU_SOCK_DEFAULT := "/tmp/pcu_bts";
type integer PCUIF_Version (9..10); /* supported versions */
type enumerated PCUIF_MsgType {
PCU_IF_MSG_DATA_REQ ('00'O),
PCU_IF_MSG_DATA_CNF ('01'O),
PCU_IF_MSG_DATA_IND ('02'O),
PCU_IF_MSG_SUSP_REQ ('03'O),
PCU_IF_MSG_APP_INFO_REQ ('04'O),
PCU_IF_MSG_RTS_REQ ('10'O),
PCU_IF_MSG_DATA_CNF_DT ('11'O),
PCU_IF_MSG_RACH_IND ('22'O),
PCU_IF_MSG_INFO_IND ('32'O),
PCU_IF_MSG_ACT_REQ ('40'O),
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_CONTAINER ('80'O),
/* Container payload message types: */
PCU_IF_MSG_NEIGH_ADDR_REQ ('81'O),
PCU_IF_MSG_NEIGH_ADDR_CNF ('82'O)
} with { variant "FIELDLENGTH(8)" };
type enumerated PCUIF_Sapi {
PCU_IF_SAPI_UNKNOWN ('00'O),
PCU_IF_SAPI_RACH ('01'O),
PCU_IF_SAPI_AGCH ('02'O),
PCU_IF_SAPI_PCH ('03'O),
PCU_IF_SAPI_BCCH ('04'O),
PCU_IF_SAPI_PDTCH ('05'O),
PCU_IF_SAPI_PRACH ('06'O),
PCU_IF_SAPI_PTCCH ('07'O),
PCU_IF_SAPI_AGCH_DT ('08'O)
} with { variant "FIELDLENGTH(8)" };
type record PCUIF_Flags {
boolean bts_active,
boolean sysmo_direct_dsp,
BIT14 spare,
boolean cs1,
boolean cs2,
boolean cs3,
boolean cs4,
boolean mcs1,
boolean mcs2,
boolean mcs3,
boolean mcs4,
boolean mcs5,
boolean mcs6,
boolean mcs7,
boolean mcs8,
boolean mcs9,
BIT3 spare2
} with { variant "" };
type enumerated PCUIF_TextType {
PCU_VERSION (0),
PCU_OML_ALERT (1)
} with { variant "FIELDLENGTH(8)" };
type charstring PCUIF_Text length(128) with { variant "FIELDLENGTH(null_terminated)" };
type record PCUIF_txt_ind {
PCUIF_TextType txt_type,
PCUIF_Text text
} with { variant "" };
type record PCUIF_data {
PCUIF_Sapi sapi,
uint8_t len,
octetstring data length(162),
uint32_t fn,
uint16_t arfcn,
uint8_t trx_nr,
uint8_t ts_nr,
uint8_t block_nr,
int8_t rssi,
uint16_t ber10k,
int16_t ta_offs_qbits,
int16_t lqual_cb
} with { variant (data) "FIELDLENGTH(162), ALIGN(left)" };
type record PCUIF_data_cnf_dt {
PCUIF_Sapi sapi,
OCT4 tlli,
uint32_t fn,
uint16_t arfcn,
uint8_t trx_nr,
uint8_t ts_nr,
uint8_t block_nr,
int8_t rssi,
uint16_t ber10k,
int16_t ta_offs_qbits,
int16_t lqual_cb
} with { variant "" };
type record PCUIF_rts_req {
PCUIF_Sapi sapi,
OCT3 spare,
uint32_t fn,
uint16_t arfcn,
uint8_t trx_nr,
uint8_t ts_nr,
uint8_t block_nr
} with { variant "" };
type enumerated PCUIF_BurstType {
BURST_TYPE_NONE (0),
BURST_TYPE_0 (1),
BURST_TYPE_1 (2),
BURST_TYPE_2 (3)
} with { variant "FIELDLENGTH(8)" };
type record PCUIF_rach_ind {
PCUIF_Sapi sapi,
uint16_t ra,
int16_t qta,
uint32_t fn,
uint16_t arfcn,
uint8_t is_11bit,
PCUIF_BurstType burst_type,
uint8_t trx_nr,
uint8_t ts_nr
} with { variant "" };
type record PCUIF_InfoTrxTs {
uint8_t tsc,
uint8_t hopping,
uint8_t hsn,
uint8_t maio,
uint8_t ma_bit_len,
bitstring ma length(64)
} with { variant (ma) "BYTEORDER(first), BITORDER(msb)" };
private type record length(8) of PCUIF_InfoTrxTs PCUIF_InfoTrxTsList;
private type record PCUIF_InfoTrx {
uint16_t arfcn,
BIT8 pdch_mask,
OCT1 spare,
uint32_t hLayer1,
PCUIF_InfoTrxTsList ts
} with { variant (pdch_mask) "BITORDER(msb)" };
type record length(8) of PCUIF_InfoTrx PCUIF_InfoTrxs;
type record PCUIF_info_ind {
uint32_t version,
PCUIF_Flags flags,
PCUIF_InfoTrxs trx,
uint8_t bsic,
uint16_t mcc,
uint16_t mnc,
uint8_t mnc_3_digits,
uint16_t lac,
uint16_t rac,
uint16_t nsei,
record length(7) of uint8_t nse_timer,
record length(11) of uint8_t cell_timer,
uint16_t cell_id,
uint16_t repeat_time,
uint8_t repeat_count,
uint16_t bvci,
uint8_t t3142,
uint8_t t3169,
uint8_t t3191,
uint8_t t3193_10ms,
uint8_t t3195,
uint8_t n3101,
uint8_t n3103,
uint8_t n3105,
uint8_t cv_countdown,
uint16_t dl_tbf_ext,
uint16_t ul_tbf_ext,
uint8_t initial_cs,
uint8_t initial_mcs,
record length(2) of uint16_t nsvci,
record length(2) of uint16_t local_port,
record length(2) of uint16_t remote_port,
PCUIF_RemoteAddr remote_addr
} with { variant "" };
type enumerated PCUIF_AddrType {
PCUIF_ADDR_TYPE_UNSPEC ('00'O),
PCUIF_ADDR_TYPE_IPV4 ('04'O),
PCUIF_ADDR_TYPE_IPV6 ('29'O)
} with { variant "FIELDLENGTH(8)" };
type record PCUIF_RemoteAddr {
record length(2) of PCUIF_AddrType addr_type,
record length(2) of octetstring addr length(16)
} with { variant "" };
type record PCUIF_act_req {
uint8_t is_activate,
uint8_t trx_nr,
uint8_t ts_nr,
OCT1 spare
} with { variant "" };
type record PCUIF_time_ind {
uint32_t fn
} with { variant "" };
type record length(8) of uint8_t PCUIF_interf;
type record PCUIF_interf_ind {
uint8_t trx_nr,
OCT3 spare,
uint32_t fn,
PCUIF_interf interf
} with { variant "" };
type record PCUIF_pag_req {
PCUIF_Sapi sapi,
uint8_t chan_needed,
OCT9 identity_lv
} with { variant "" };
type record PCUIF_app_info_req {
uint8_t application_type,
uint8_t len,
octetstring data
} with {
variant (len) "LENGTHTO(data)"
}
type record PCUIF_susp_req {
OCT4 tlli,
OCT6 ra_id,
uint8_t cause
} with {
variant (tlli) "BYTEORDER(last)"
};
type record PCUIF_neigh_addr_req {
uint16_t local_lac,
uint16_t local_ci,
uint16_t tgt_arfcn,
uint8_t tgt_bsic
} with { variant (local_lac) "BYTEORDER(last)"
variant (local_ci) "BYTEORDER(last)"
variant (tgt_arfcn) "BYTEORDER(last)" };
type record PCUIF_neigh_addr_cnf {
PCUIF_neigh_addr_req orig_req,
uint8_t error_code,
uint16_t mcc,
uint16_t mnc,
uint8_t mnc_3_digits,
uint16_t lac,
uint8_t rac,
uint16_t cell_identity
} with { variant (mcc) "BYTEORDER(last)"
variant (mnc) "BYTEORDER(last)"
variant (lac) "BYTEORDER(last)"
variant (cell_identity) "BYTEORDER(last)" };
type union PCUIF_ContainerMsgUnion {
PCUIF_neigh_addr_req neigh_addr_req,
PCUIF_neigh_addr_cnf neigh_addr_cnf,
octetstring other
} with { variant "" };
type record PCUIF_container {
PCUIF_MsgType 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(
neigh_addr_req, msg_type = PCU_IF_MSG_NEIGH_ADDR_REQ;
neigh_addr_cnf, msg_type = PCU_IF_MSG_NEIGH_ADDR_CNF;
other, OTHERWISE)"
};
type union PCUIF_MsgUnion {
PCUIF_data data_req,
PCUIF_data data_cnf,
PCUIF_data_cnf_dt data_cnf_dt,
PCUIF_data data_ind,
PCUIF_susp_req susp_req,
PCUIF_rts_req rts_req,
PCUIF_rach_ind rach_ind,
PCUIF_txt_ind txt_ind,
PCUIF_info_ind info_ind,
PCUIF_act_req act_req,
PCUIF_time_ind time_ind,
PCUIF_interf_ind interf_ind,
PCUIF_pag_req pag_req,
PCUIF_app_info_req app_info_req,
PCUIF_container container
} with { variant "" };
type record PCUIF_Message {
PCUIF_MsgType msg_type,
uint8_t bts_nr,
OCT2 spare,
PCUIF_MsgUnion u
} with { variant (u) "CROSSTAG(
data_req, msg_type = PCU_IF_MSG_DATA_REQ;
data_cnf, msg_type = PCU_IF_MSG_DATA_CNF;
data_cnf_dt, msg_type = PCU_IF_MSG_DATA_CNF_DT;
data_ind, msg_type = PCU_IF_MSG_DATA_IND;
susp_req, msg_type = PCU_IF_MSG_SUSP_REQ;
rts_req, msg_type = PCU_IF_MSG_RTS_REQ;
rach_ind, msg_type = PCU_IF_MSG_RACH_IND;
txt_ind, msg_type = PCU_IF_MSG_TXT_IND;
info_ind, msg_type = PCU_IF_MSG_INFO_IND;
act_req, msg_type = PCU_IF_MSG_ACT_REQ;
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;
container, msg_type = PCU_IF_MSG_CONTAINER)"
/* PCUIFv10: 1006 * 8 = 8048 bits */
variant "PADDING(8048)"
};
external function enc_PCUIF_Message(in PCUIF_Message pdu) return octetstring
with { extension "prototype(convert) encode(RAW)" };
external function dec_PCUIF_Message(in octetstring stream) return PCUIF_Message
with { extension "prototype(convert) decode(RAW)" };
Introduce PCUIF, BTS and ClckGen components for RAW PCU test cases The problem of existing test cases is that they mix IUT (i.e. OsmoPCU) with OsmoBTS (osmo-bts-virtual) and OsmocomBB (virt_phy). This approach allows to avoid dealing with TDMA clock indications and RTS requests on the PCU interface - this is done by OsmoBTS. On the other hand, our test scenarios may be potentially affected by undiscovered bugs in OsmoBTS and the virt_phy. In order to solve that problem, this change introduces a set of new components and the corresponding handler functions: - RAW_PCUIF_CT / f_PCUIF_CT_handler() - PCU interface (UNIX domain socket) handler. Creates a server listening for incoming connections on a given 'pcu_sock_path', handles connection establishment and message forwarding between connected BTS components (see below) and OsmoPCU. - RAW_PCU_BTS_CT / f_BTS_CT_handler() - represents a single BTS entity, connected to OsmoPCU through the RAW_PCUIF_CT. Takes care about sending System Information 13 to OsmoPCU, forwarding TDMA clock indications from a dedicated ClckGen component (see below), and filtering the received messages by the BTS number. Implements minimalistic scheduler for both DATA.ind and RTS.req messages, so they are send in accordance with the current TDMA frame number. - RAW_PCU_ClckGen_CT / f_ClckGen_CT_handler() - TDMA frame clock counter built on top of a timer. Sends clock indications to the BTS component. All components communicate using TTCN-3 ports and explicitly defined sets of messages (see RAW_PCU_MSG_PT). One noticeable kind of such messages is events (see RAW_PCU_Event and RAW_PCU_EventType). That's how e.g. the PCUIF component can notify the BTS component that OsmoPCU has just connected, or the BTS component can notify the MTC that SI13 negotiation is completed. Events may optionally have parameters (e.g. frame-number for TDMA_EV_*). Furthermore, the proposed set of components allows to have more than one BTS entity, so we can also test multi-BTS operation in the future. +-----+ +----------+ +---------+ | MTC +---------------+ PCUIF_CT +------+ OsmoPCU | +--+--+ +----+-----+ +---------+ | | | | | | | +-----------+ | +---------------+ +----+ BTS_CT #1 +------+ | ClckGen_CT #1 | | +-----+-----+ | +-------+-------+ | | | | | +---------------------------+ | | | +-----------+ | +---------------+ +----+ BTS_CT #2 +------+ | ClckGen_CT #2 | | +-----+-----+ | +-------+-------+ | | | | | +---------------------------+ | | | +-----------+ | +---------------+ +----+ BTS_CT #N +------+ | ClckGen_CT #N | +-----+-----+ +-------+-------+ | | +---------------------------+ Change-Id: I63a23abebab88fd5318eb4d907d6028e7c38e9a3
2019-09-05 22:08:17 +00:00
/* Generic template for matching messages by type and/or the BTS number */
template PCUIF_Message tr_PCUIF_MSG(template PCUIF_MsgType msg_type := ?,
template uint8_t bts_nr := ?) := {
msg_type := msg_type,
bts_nr := bts_nr,
spare := ?,
u := ?
}
template (value) PCUIF_Message ts_PCUIF_RTS_REQ(template (value) uint8_t bts_nr,
template (value) uint8_t trx_nr,
template (value) uint8_t ts_nr,
template (value) PCUIF_Sapi sapi,
template (value) uint32_t fn,
template (value) uint16_t arfcn,
template (value) uint8_t block_nr
) := {
msg_type := PCU_IF_MSG_RTS_REQ,
bts_nr := bts_nr,
spare := '0000'O,
u := {
rts_req := {
sapi := sapi,
spare := '000000'O,
fn := fn,
arfcn := arfcn,
trx_nr := trx_nr,
ts_nr := ts_nr,
block_nr := block_nr
}
}
}
template PCUIF_Message tr_PCUIF_RTS_REQ(template uint8_t bts_nr := ?,
template uint8_t trx_nr := ?,
template uint8_t ts_nr := ?,
template PCUIF_Sapi sapi := ?,
template uint32_t fn := ?,
template uint8_t block_nr := ?
) := {
msg_type := PCU_IF_MSG_RTS_REQ,
bts_nr := bts_nr,
spare := ?,
u := {
rts_req := {
sapi := sapi,
spare := ?,
fn := fn,
arfcn := ?,
trx_nr := trx_nr,
ts_nr := ts_nr,
block_nr := block_nr
}
}
}
template (value) PCUIF_Message ts_PCUIF_TXT_IND(uint8_t bts_nr, PCUIF_TextType tt, charstring text) := {
msg_type := PCU_IF_MSG_TXT_IND,
bts_nr := bts_nr,
spare := '0000'O,
u := {
txt_ind := {
txt_type := tt,
text := text
}
}
}
template PCUIF_Message tr_PCUIF_TXT_IND(template uint8_t bts_nr, template PCUIF_TextType tt,
template charstring text := ?) := {
msg_type := PCU_IF_MSG_TXT_IND,
bts_nr := bts_nr,
spare := '0000'O,
u := {
txt_ind := {
txt_type := tt,
text := text
}
}
}
template (value) PCUIF_Message ts_PCUIF_ACT_REQ(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr) := {
msg_type := PCU_IF_MSG_ACT_REQ,
bts_nr := bts_nr,
spare := '0000'O,
u := {
act_req := {
is_activate := 1,
trx_nr := trx_nr,
ts_nr := ts_nr,
spare := '00'O
}
}
}
template PCUIF_Message tr_PCUIF_ACT_REQ(template uint8_t bts_nr, template uint8_t trx_nr,
template uint8_t ts_nr) := {
msg_type := PCU_IF_MSG_ACT_REQ,
bts_nr := bts_nr,
spare := '0000'O,
u := {
act_req := {
is_activate := 1,
trx_nr := trx_nr,
ts_nr := ts_nr,
spare := '00'O
}
}
}
template (value) PCUIF_Message ts_PCUIF_DEACT_REQ(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr) := {
msg_type := PCU_IF_MSG_ACT_REQ,
bts_nr := bts_nr,
spare := '0000'O,
u := {
act_req := {
is_activate := 0,
trx_nr := trx_nr,
ts_nr := ts_nr,
spare := '00'O
}
}
}
template PCUIF_Message tr_PCUIF_DEACT_REQ(template uint8_t bts_nr, template uint8_t trx_nr,
template uint8_t ts_nr) := {
msg_type := PCU_IF_MSG_ACT_REQ,
bts_nr := bts_nr,
spare := '0000'O,
u := {
act_req := {
is_activate := 0,
trx_nr := trx_nr,
ts_nr := ts_nr,
spare := '00'O
}
}
}
template (value) PCUIF_Message ts_PCUIF_DATA_IND(template (value) uint8_t bts_nr,
template (value) uint8_t trx_nr,
template (value) uint8_t ts_nr,
template (value) uint8_t block_nr,
template (value) PCUIF_Sapi sapi,
template (value) octetstring data,
template (value) uint32_t fn,
template (value) uint16_t arfcn,
template (value) int8_t rssi := -80,
template (value) uint16_t ber10k := 0,
template (value) int16_t ta_offs_qbits := 0,
template (value) int16_t lqual_cb := 10) := {
msg_type := PCU_IF_MSG_DATA_IND,
bts_nr := bts_nr,
spare := '0000'O,
u := {
data_ind := {
sapi := sapi,
len := lengthof(valueof(data)),
data := data,
fn := fn,
arfcn := arfcn,
trx_nr := trx_nr,
ts_nr := ts_nr,
block_nr := block_nr,
rssi := rssi,
ber10k := ber10k,
ta_offs_qbits := ta_offs_qbits,
lqual_cb := lqual_cb
}
}
}
template PCUIF_Message tr_PCUIF_DATA_IND(template uint8_t bts_nr := ?,
template uint8_t trx_nr := ?,
template uint8_t ts_nr := ?,
template uint8_t block_nr := ?,
template PCUIF_Sapi sapi := ?,
template octetstring data := ?) := {
msg_type := PCU_IF_MSG_DATA_IND,
bts_nr := bts_nr,
spare := ?,
u := {
data_ind := {
sapi := sapi,
len := ?,
data := data,
fn := ?,
arfcn := ?,
trx_nr := trx_nr,
ts_nr := ts_nr,
block_nr := block_nr,
rssi := ?,
ber10k := ?,
ta_offs_qbits := ?,
lqual_cb := ?
}
}
}
template PCUIF_data tr_PCUIF_DATA(template uint8_t trx_nr,
template uint8_t ts_nr,
template uint8_t block_nr := ?,
template uint32_t fn := ?,
template PCUIF_Sapi sapi := ?,
template octetstring data := ?) := {
sapi := sapi,
len := ?,
data := data,
fn := fn,
arfcn := ?, /* unused in BTS */
trx_nr := trx_nr,
ts_nr := ts_nr,
block_nr := block_nr,
/* measurement parameters below unused on Tx */
rssi := 0,
ber10k := 0,
ta_offs_qbits := 0,
lqual_cb := 0
}
template (value) PCUIF_Message ts_PCUIF_DATA_REQ(uint8_t bts_nr, uint8_t trx_nr,
uint8_t ts_nr, uint8_t block_nr,
uint32_t fn, PCUIF_Sapi sapi,
octetstring data) := {
msg_type := PCU_IF_MSG_DATA_REQ,
bts_nr := bts_nr,
spare := '0000'O,
u := {
data_req := {
sapi := sapi,
len := lengthof(data),
data := data,
fn := fn,
arfcn := 0, /* unused in BTS */
trx_nr := trx_nr,
ts_nr := ts_nr,
block_nr := block_nr,
/* measurement parameters below unused on Tx */
rssi := 0,
ber10k := 0,
ta_offs_qbits := 0,
lqual_cb := 0
}
}
}
template PCUIF_Message tr_PCUIF_DATA_REQ(template uint8_t bts_nr,
template uint8_t trx_nr,
template uint8_t ts_nr,
template uint8_t block_nr := ?,
template uint32_t fn := ?,
template PCUIF_Sapi sapi := ?,
template octetstring data := ?) := {
msg_type := PCU_IF_MSG_DATA_REQ,
bts_nr := bts_nr,
spare := '0000'O,
u := {
data_req := tr_PCUIF_DATA(trx_nr, ts_nr, block_nr, fn, sapi, data)
}
}
template (value) PCUIF_Message ts_PCUIF_DATA_CNF(template (value) uint8_t bts_nr,
template (value) uint8_t trx_nr,
template (value) uint8_t ts_nr,
template (value) uint8_t block_nr,
template (value) uint32_t fn,
template (value) uint16_t arfcn,
template (value) PCUIF_Sapi sapi,
template (value) octetstring data) := {
msg_type := PCU_IF_MSG_DATA_CNF,
bts_nr := bts_nr,
spare := '0000'O,
u := {
data_cnf := {
sapi := sapi,
len := 0, /* overwritten */
data := data,
fn := fn,
arfcn := arfcn,
trx_nr := trx_nr,
ts_nr := ts_nr,
block_nr := block_nr,
rssi := 0,
ber10k := 0,
ta_offs_qbits := 0,
lqual_cb := 0
}
}
}
template PCUIF_Message tr_PCUIF_DATA_CNF(template uint8_t bts_nr := ?,
template uint8_t trx_nr := ?,
template uint8_t ts_nr := ?,
template PCUIF_Sapi sapi := ?,
template octetstring data := ?) := {
msg_type := PCU_IF_MSG_DATA_CNF,
bts_nr := bts_nr,
spare := ?,
u := {
data_cnf := {
sapi := sapi,
len := ?,
data := data,
fn := ?,
arfcn := ?,
trx_nr := trx_nr,
ts_nr := ts_nr,
block_nr := ?,
rssi := ?,
ber10k := ?,
ta_offs_qbits := ?,
lqual_cb := ?
}
}
}
template (value) PCUIF_Message ts_PCUIF_RACH_IND(template (value) uint8_t bts_nr,
template (value) uint8_t trx_nr,
template (value) uint8_t ts_nr,
template (value) uint16_t ra,
template (value) uint8_t is_11bit,
template (value) PCUIF_BurstType burst_type,
template (value) uint32_t fn,
template (value) uint16_t arfcn,
template (value) int16_t qta := 0,
template (value) PCUIF_Sapi sapi := PCU_IF_SAPI_RACH
) := {
msg_type := PCU_IF_MSG_RACH_IND,
bts_nr := bts_nr,
spare := '0000'O,
u := {
rach_ind := {
sapi := sapi,
ra := ra,
qta := qta,
fn := fn,
arfcn := arfcn,
is_11bit := is_11bit,
burst_type := burst_type,
trx_nr := trx_nr,
ts_nr := ts_nr
}
}
}
template PCUIF_Message tr_PCUIF_RACH_IND(template uint8_t bts_nr := ?,
template uint8_t trx_nr := ?,
template uint8_t ts_nr := ?,
template uint16_t ra := ?,
template uint8_t is_11bit := ?,
template PCUIF_BurstType burst_type := ?,
template uint32_t fn := ?,
template PCUIF_Sapi sapi := PCU_IF_SAPI_RACH) := {
msg_type := PCU_IF_MSG_RACH_IND,
bts_nr := bts_nr,
spare := ?,
u := {
rach_ind := {
sapi := sapi,
ra := ra,
qta := ?,
fn := fn,
arfcn := ?,
is_11bit := is_11bit,
burst_type := burst_type,
trx_nr := trx_nr,
ts_nr := ts_nr
}
}
}
template (value) PCUIF_Message ts_PCUIF_PAG_REQ(template (value) uint8_t bts_nr,
template (value) OCT9 id_lv,
template (value) uint8_t chan_needed,
template (value) PCUIF_Sapi sapi) := {
msg_type := PCU_IF_MSG_PAG_REQ,
bts_nr := bts_nr,
spare := '0000'O,
u := {
pag_req := {
sapi := sapi,
chan_needed := chan_needed,
identity_lv := id_lv
}
}
}
template PCUIF_Message tr_PCUIF_PAG_REQ(template uint8_t bts_nr := ?,
template OCT9 id_lv := ?,
template uint8_t chan_needed := ?,
template PCUIF_Sapi sapi := ?) := {
msg_type := PCU_IF_MSG_PAG_REQ,
bts_nr := bts_nr,
spare := ?,
u := {
pag_req := {
sapi := ?,
chan_needed := chan_needed,
identity_lv := id_lv
}
}
}
const PCUIF_Flags c_PCUIF_Flags_default := {
bts_active := true,
sysmo_direct_dsp := false,
spare := '00000000000000'B,
cs1 := true,
cs2 := true,
cs3 := true,
cs4 := true,
mcs1 := true,
mcs2 := true,
mcs3 := true,
mcs4 := true,
mcs5 := true,
mcs6 := true,
mcs7 := true,
mcs8 := true,
mcs9 := true,
spare2 := '000'B
};
const PCUIF_Flags c_PCUIF_Flags_noMCS := {
bts_active := true,
sysmo_direct_dsp := false,
spare := '00000000000000'B,
cs1 := true,
cs2 := true,
cs3 := true,
cs4 := true,
mcs1 := false,
mcs2 := false,
mcs3 := false,
mcs4 := false,
mcs5 := false,
mcs6 := false,
mcs7 := false,
mcs8 := false,
mcs9 := false,
spare2 := '000'B
};
function f_pcuif_ind_flags_egprs_enabled(PCUIF_Flags flags) return boolean {
return flags.mcs1 or flags.mcs2 or flags.mcs3 or flags.mcs4 or
flags.mcs5 or flags.mcs6 or flags.mcs7 or flags.mcs8 or
flags.mcs9;
}
template (value) PCUIF_InfoTrxTs ts_PCUIF_InfoTrxTsH0(template (value) uint3_t tsc := 7) := {
tsc := tsc,
hopping := 0,
hsn := 0, maio := 0,
ma_bit_len := 0,
ma := f_pad_bit(''B, 64, '0'B)
};
template PCUIF_InfoTrxTs tr_PCUIF_InfoTrxTsH0(template uint3_t tsc := ?) := {
tsc := tsc,
hopping := 0,
hsn := ?, maio := ?,
ma_bit_len := ?,
ma := ?
};
template (value) PCUIF_InfoTrxTs ts_PCUIF_InfoTrxTsH1(template (value) uint3_t tsc := 7,
template (value) uint6_t hsn := 0,
template (value) uint6_t maio := 0,
template (value) bitstring ma := ''B) := {
tsc := tsc,
hopping := 1,
hsn := hsn,
maio := maio,
ma_bit_len := lengthof(valueof(ma)),
ma := f_pad_bit(valueof(ma), 64, '0'B)
};
template PCUIF_InfoTrxTs tr_PCUIF_InfoTrxTsH1(template uint3_t tsc := ?,
template uint6_t hsn := ?,
template uint6_t maio := ?,
template bitstring ma := ?,
template uint8_t ma_bit_len := ?) := {
tsc := tsc,
hopping := 1,
hsn := hsn,
maio := maio,
ma_bit_len := ma_bit_len,
ma := ma
};
template (value) PCUIF_InfoTrx
ts_PCUIF_InfoTrx(template (value) uint16_t arfcn := 871,
template (value) BIT8 pdch_mask := '00000001'B,
template (value) uint3_t tsc := 7) := {
arfcn := arfcn,
pdch_mask := pdch_mask,
spare := '00'O,
hLayer1 := 0,
ts := {
ts_PCUIF_InfoTrxTsH0(tsc), ts_PCUIF_InfoTrxTsH0(tsc),
ts_PCUIF_InfoTrxTsH0(tsc), ts_PCUIF_InfoTrxTsH0(tsc),
ts_PCUIF_InfoTrxTsH0(tsc), ts_PCUIF_InfoTrxTsH0(tsc),
ts_PCUIF_InfoTrxTsH0(tsc), ts_PCUIF_InfoTrxTsH0(tsc)
}
};
template (value) PCUIF_InfoTrxs
ts_PCUIF_InfoTrxs_def(uint16_t base_arfcn) := {
ts_PCUIF_InfoTrx(arfcn := base_arfcn + 0),
ts_PCUIF_InfoTrx(arfcn := base_arfcn + 1),
ts_PCUIF_InfoTrx(arfcn := base_arfcn + 2),
ts_PCUIF_InfoTrx(arfcn := base_arfcn + 3),
ts_PCUIF_InfoTrx(arfcn := base_arfcn + 4),
ts_PCUIF_InfoTrx(arfcn := base_arfcn + 5),
ts_PCUIF_InfoTrx(arfcn := base_arfcn + 6),
ts_PCUIF_InfoTrx(arfcn := base_arfcn + 7)
};
template (value) PCUIF_Message ts_PCUIF_INFO_IND(template (value) uint8_t bts_nr,
template (value) PCUIF_info_ind info_ind) := {
msg_type := PCU_IF_MSG_INFO_IND,
bts_nr := bts_nr,
spare := '0000'O,
u := {
info_ind := info_ind
}
}
template PCUIF_Message tr_PCUIF_INFO_IND(template uint8_t bts_nr := ?,
template PCUIF_Flags flags := ?,
template uint32_t version := mp_pcuif_version) := {
msg_type := PCU_IF_MSG_INFO_IND,
bts_nr := bts_nr,
spare := ?,
u := {
info_ind := {
version := version,
flags := flags,
trx := ?,
bsic := ?,
mcc := ?,
mnc :=?,
mnc_3_digits := ?,
lac := ?,
rac := ?,
nsei := ?,
nse_timer := ?,
cell_timer := ?,
cell_id := ?,
repeat_time := ?,
repeat_count := ?,
bvci := ?,
t3142 := ?,
t3169 := ?,
t3191 := ?,
t3193_10ms := ?,
t3195 := ?,
n3101 := ?,
n3103 := ?,
n3105 := ?,
cv_countdown := ?,
dl_tbf_ext := ?,
ul_tbf_ext := ?,
initial_cs := ?,
initial_mcs := ?,
nsvci := ?,
local_port := ?,
remote_port := ?,
remote_addr := ?
}
}
}
template (value) PCUIF_Message ts_PCUIF_TIME_IND(template (value) uint8_t bts_nr,
template (value) uint32_t fn) := {
msg_type := PCU_IF_MSG_TIME_IND,
bts_nr := bts_nr,
spare := '0000'O,
u := {
time_ind := {
fn := fn
}
}
}
template PCUIF_Message tr_PCUIF_TIME_IND(template uint8_t bts_nr,
template uint32_t fn) := {
msg_type := PCU_IF_MSG_TIME_IND,
bts_nr := bts_nr,
spare := ?,
u := {
time_ind := {
fn := fn
}
}
}
template (value) PCUIF_Message
ts_PCUIF_INTERF_IND(template (value) uint8_t bts_nr,
template (value) uint8_t trx_nr,
template (value) uint32_t fn,
template (value) PCUIF_interf interf) := {
msg_type := PCU_IF_MSG_INTERF_IND,
bts_nr := bts_nr,
spare := '0000'O,
u := {
interf_ind := {
trx_nr := trx_nr,
spare := '000000'O,
fn := fn,
interf := interf
}
}
}
template PCUIF_Message
tr_PCUIF_INTERF_IND(template (present) uint8_t bts_nr := ?,
template (present) uint8_t trx_nr := ?,
template (present) uint32_t fn := ?,
template (present) PCUIF_interf interf := ?) := {
msg_type := PCU_IF_MSG_INTERF_IND,
bts_nr := bts_nr,
spare := ?,
u := {
interf_ind := {
trx_nr := trx_nr,
spare := ?,
fn := fn,
interf := interf
}
}
}
template (value) PCUIF_Message ts_PCUIF_SUSP_REQ(template (value) uint8_t bts_nr,
template (value) OCT4 tlli,
template (value) OCT6 ra_id,
template (value) uint8_t cause) := {
msg_type := PCU_IF_MSG_SUSP_REQ,
bts_nr := bts_nr,
spare := '0000'O,
u := {
susp_req := {
tlli := tlli,
ra_id := ra_id,
cause := cause
}
}
}
template PCUIF_Message tr_PCUIF_SUSP_REQ(template uint8_t bts_nr,
template OCT4 tlli,
template OCT6 ra_id,
template uint8_t cause) := {
msg_type := PCU_IF_MSG_SUSP_REQ,
bts_nr := bts_nr,
spare := '0000'O,
u := {
susp_req := {
tlli := tlli,
ra_id := ra_id,
cause := cause
}
}
}
template (value) PCUIF_Message ts_PCUIF_APP_INFO_REQ(template (value) uint8_t bts_nr,
template (value) uint8_t app_type,
template (value) octetstring app_data) := {
msg_type := PCU_IF_MSG_APP_INFO_REQ,
bts_nr := bts_nr,
spare := '0000'O,
u := {
app_info_req := {
application_type := app_type,
len := 0, /* overwritten */
data := app_data
}
}
}
template (present) PCUIF_Message tr_PCUIF_APP_INFO_REQ(template (present) uint8_t bts_nr,
template (present) uint8_t app_type,
template (present) octetstring app_data) := {
msg_type := PCU_IF_MSG_APP_INFO_REQ,
bts_nr := bts_nr,
spare := '0000'O,
u := {
app_info_req := {
application_type := app_type,
len := ?,
data := app_data
}
}
}
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(PCUIF_MsgType 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) PCUIF_MsgType msg_type,
template (present) octetstring payload) := {
msg_type := msg_type,
spare := '00'O,
len := ?,
u := {
other := payload
}
}
template (present) PCUIF_container tr_PCUIF_CONT_NEIGH_ADDR_REQ(template (present) uint16_t local_lac := ?,
template (present) uint16_t local_ci := ?,
template (present) uint16_t tgt_arfcn := ?,
template (present) uint8_t tgt_bsic := ?) := {
msg_type := PCU_IF_MSG_NEIGH_ADDR_REQ,
spare := '00'O,
len := ?,
u := {
neigh_addr_req := {
local_lac := local_lac,
local_ci := local_ci,
tgt_arfcn := tgt_arfcn,
tgt_bsic := tgt_bsic
}
}
}
template (present) PCUIF_Message tr_PCUIF_NEIGH_ADDR_REQ(template (present) uint8_t bts_nr,
template (present) uint16_t local_lac := ?,
template (present) uint16_t local_ci := ?,
template (present) uint16_t tgt_arfcn := ?,
template (present) uint8_t tgt_bsic := ?) := {
msg_type := PCU_IF_MSG_CONTAINER,
bts_nr := bts_nr,
spare := '0000'O,
u := {
container := tr_PCUIF_CONT_NEIGH_ADDR_REQ(local_lac, local_ci, tgt_arfcn, tgt_bsic)
}
}
template (value) PCUIF_container ts_PCUIF_CONT_NEIGH_ADDR_CNF(template (value) PCUIF_neigh_addr_req orig_req,
template (value) uint8_t error_code := 0,
template (value) uint16_t mcc := 0,
template (value) uint16_t mnc := 0,
template (value) uint8_t mnc_3_digits := 0,
template (value) uint16_t lac := 0,
template (value) uint8_t rac := 0,
template (value) uint16_t cell_identity := 0) := {
msg_type := PCU_IF_MSG_NEIGH_ADDR_CNF,
spare := '00'O,
len := 0, /* overwritten */
u := {
neigh_addr_cnf := {
orig_req := orig_req,
error_code := error_code,
mcc := mcc,
mnc := mnc,
mnc_3_digits := mnc_3_digits,
lac := lac,
rac := rac,
cell_identity := cell_identity
}
}
}
template (value) PCUIF_Message ts_PCUIF_NEIGH_ADDR_CNF(template (value) uint8_t bts_nr,
template (value) PCUIF_neigh_addr_req orig_req,
template (value) uint8_t error_code := 0,
template (value) uint16_t mcc := 0,
template (value) uint16_t mnc := 0,
template (value) uint8_t mnc_3_digits := 0,
template (value) uint16_t lac := 0,
template (value) uint8_t rac := 0,
template (value) uint16_t cell_identity := 0) := {
msg_type := PCU_IF_MSG_CONTAINER,
bts_nr := bts_nr,
spare := '0000'O,
u := {
container := ts_PCUIF_CONT_NEIGH_ADDR_CNF(orig_req, error_code, mcc, mnc, mnc_3_digits,
lac, rac, cell_identity)
}
}
function f_PCUIF_PDCHMask_set(inout PCUIF_info_ind info, BIT8 pdch_mask,
template (present) uint8_t trx_nr := ?)
{
for (var integer nr := 0; nr < lengthof(info.trx); nr := nr + 1) {
if (match(nr, trx_nr)) {
info.trx[nr].pdch_mask := pdch_mask;
}
}
}
function f_PCUIF_AF2addr_type(AddressFamily address_family)
return PCUIF_AddrType {
if (address_family == AF_INET) {
return PCUIF_ADDR_TYPE_IPV4;
} else if (address_family == AF_INET6) {
return PCUIF_ADDR_TYPE_IPV6;
} else {
return PCUIF_ADDR_TYPE_UNSPEC;
}
}
/* TODO: second (redundant) NSVC connection is not (yet) supported */
function f_PCUIF_RemoteAddr(PCUIF_AddrType addr_type,
charstring addr_str)
return PCUIF_RemoteAddr {
var PCUIF_RemoteAddr remote_addr;
remote_addr.addr_type[0] := addr_type;
if (addr_type == PCUIF_ADDR_TYPE_IPV4) {
remote_addr.addr[0] := f_inet_addr(addr_str);
} else {
remote_addr.addr[0] := f_inet6_addr(addr_str);
}
remote_addr.addr_type[1] := PCUIF_ADDR_TYPE_UNSPEC;
remote_addr.addr[1] := f_pad_oct(''O, 16, '00'O);
return remote_addr;
}
} with { encode "RAW" variant "BYTEORDER(first)" };