/* Osmocom PCU Interface Types, as per osmo-pcu/include/osmocom/pcu/pcuif_proto.h * (C) 2018-2019 Harald Welte * contributions by Vadim Yanitskiy * 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)" }; /* 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)" };