Migrate Gb (NS/BSSGP) code over to Ericsson NS/BSSGP modules

When we started out, Ericsson hadn't released yet their NS and BSSGP
modules.  Let's port our logic over to their encoder/decoders, as they
are more complete (but less regular / more difficult to use).

Change-Id: Icbc4f5d24f3419f99c9a4805f836bddd2849f492
This commit is contained in:
Harald Welte 2018-02-05 09:13:31 +01:00
parent 2f8eed0aac
commit e0abc47d32
7 changed files with 737 additions and 143 deletions

View File

@ -4,7 +4,7 @@ module Test {
import from Osmocom_Types all;
import from GSM_Types all;
import from GSM_RR_Types all;
import from BSSGP_Helper_Functions all;
import from Osmocom_Gb_Types all;
import from BSSGP_Types all;
import from BSSGP_Emulation all;
import from NS_Types all;
@ -16,7 +16,7 @@ module Test {
type record MmContext {
octetstring imsi optional,
BssgpTlli tlli,
GprsTlli tlli,
uint9_t n_u
};
@ -59,24 +59,9 @@ module Test {
lapdm_component.start(LAPDmStart());
}
function f_bssgp_assert_prepr(in octetstring a, in octetstring b) {
log("BSSGP Input: ", a);
log("BSSGP Expected: ", b);
var octetstring a_preprocessed := f_BSSGP_expand_len(a);
log("BSSGP Preprocessed: ", a_preprocessed);
if (a_preprocessed != b) {
setverdict(fail);
} else {
setverdict(pass);
}
}
function f_bssgp_dec_and_log(in octetstring inp) {
log("BSSGP Input: ", inp);
var octetstring inp_p := f_BSSGP_expand_len(inp);
log("BSSGP Preprocessed: ", inp_p);
var BssgpPdu dec := dec_BssgpPdu(inp_p);
var PDU_BSSGP dec := dec_PDU_BSSGP(inp);
log("BSSGP Decoded: ", dec);
}
@ -97,18 +82,6 @@ module Test {
const octetstring c_gmm_mt_det_req := '00bb146ddd0050001682ffff0a8204030e8941c00908050215f0b6'O;
const octetstring c_gmm_mo_att_cpl := '01fb146ddd000004088832f44000c80051e000800e000801c009080339d7bc'O;
/* single byte length to two byte length */
f_bssgp_assert_prepr('04058101'O, '0405000101'O);
f_bssgp_assert_prepr('040589000102030405060708'O, '04050009000102030405060708'O);
/* two byte length to two byte length */
f_bssgp_assert_prepr('0405000101'O, '0405000101'O);
/* special case: DL-UD + UL-UD */
f_bssgp_assert_prepr('00aabbccddeeffaa29822342'O, '00aabbccddeeffaa2900022342'O);
f_bssgp_assert_prepr('01aabbccddeeffaa29822342'O, '01aabbccddeeffaa2900022342'O);
/* multiple TLVs */
f_bssgp_assert_prepr('234281aa4382bbbb'O, '23420001aa430002bbbb'O);
f_bssgp_assert_prepr('230080'O, '23000000'O);
f_bssgp_dec_and_log(c_bvc_reset_pcu);
f_bssgp_dec_and_log(c_bvc_reset_q);
f_bssgp_dec_and_log(c_status_pcu);
@ -125,16 +98,14 @@ module Test {
f_bssgp_dec_and_log(c_gmm_mt_det_req);
f_bssgp_dec_and_log(c_gmm_mo_att_cpl);
log(t_BSSGP_PS_PAGING_IMSI(196, '262420123456789'H));
log(ts_BSSGP_PS_PAGING_IMSI(196, '262420123456789'H));
}
function f_ns_assert_prepr(in octetstring a, in octetstring b) {
log("NS Input: ", a);
log("NS Expected: ", b);
var octetstring a_preprocessed := f_NS_expand_len(a);
log("NS Preprocessed: ", a_preprocessed);
if (a_preprocessed != b) {
if (a != b) {
setverdict(fail);
} else {
setverdict(pass);
@ -143,9 +114,7 @@ module Test {
function f_ns_dec_and_log(in octetstring inp) {
log("NS Input: ", inp);
var octetstring inp_p := f_NS_expand_len(inp);
log("NS Preprocessed: ", inp_p);
var NsPdu dec := dec_NsPdu(inp_p);
var PDU_NS dec := dec_PDU_NS(inp);
log("NS Decoded: ", dec);
}
@ -167,57 +136,6 @@ module Test {
f_ns_dec_and_log(c_ns_reset_pcu);
}
const BssgpQosProfile c_DefaultQos := { r := 80, spare := '00'B, c_r := false, t := false, a := false, precedence := 0 };
template BssgpTLV c_DefaultLifetimeTLV := t_BSSGP_IE_Lifetime(65535);
template BssgpTLV t_BSSGP_IE_LLC_PDU(LlcPdu llc) := t_BssgpIE(LLC_PDU, { other := f_LLC_append_fcs(enc_LlcPdu(llc)) });
template BssgpPdu t_BSSGP_DL_UD(BssgpTlli tlli, LlcPdu llc, BssgpTLVs opt_tlvs := {}) := {
pdu_type := DL_UNITDATA,
u := {
dl_unitdata := {
tlli := tlli,
qos_profile := c_DefaultQos,
pdu_lifetime := c_DefaultLifetimeTLV,
//tlvs := opt_tlvs & { t_BSSGP_IE_LLC_PDU(llc) }
tlvs := { t_BSSGP_IE_LLC_PDU(llc) }
}
}
};
template BssgpPdu t_BSSGP_UL_UD(template BssgpTlli tlli, template BssgpCellId cell_id, template octetstring payload) := {
pdu_type := UL_UNITDATA,
u := {
ul_unitdata := {
tlli := tlli,
qos_profile := ?,
cell_id := { iei := CELL_ID, len := 8, u := { cell_id := cell_id } },
tlvs := {
{ iei := ALIGNMENT_OCTETS, len := ?, u := { other := ? } },
{ iei := LLC_PDU, len := ?, u := { other := payload } }
}
}
}
}
template BssgpPdu t_BSSGP_PS_PAGING_IMSI(BssgpBvci bvci, hexstring imsi) := {
pdu_type := PAGING_PS,
u := {
other := {
tlvs := { t_BSSGP_IE_Imsi(imsi), t_BSSGP_IE_Bvci(bvci), t_BSSGP_IE_Qos(c_DefaultQos) }
}
}
};
template BssgpPdu t_BSSGP_PS_PAGING_PTMSI(BssgpBvci bvci, hexstring imsi, GsmTmsi ptmsi) := {
pdu_type := PAGING_PS,
u := {
other := {
tlvs := { t_BSSGP_IE_Imsi(imsi), t_BSSGP_IE_Bvci(bvci), t_BSSGP_IE_Qos(c_DefaultQos), t_BSSGP_IE_Tmsi(ptmsi) }
}
}
};
const octetstring gmm_auth_req := '081200102198c72477ea104895e8b959acc58b108182'O;
function tx_gmm(boolean c_r, in octetstring gmm_pdu, LlcSapi sapi := LLC_SAPI_GMM) runs on dummy_CT {
@ -231,9 +149,9 @@ module Test {
log(llc);
g_mmctx.n_u := g_mmctx.n_u + 1;
log(t_BSSGP_DL_UD(g_mmctx.tlli, llc));
log(ts_BSSGP_DL_UD(g_mmctx.tlli, enc_LlcPdu(llc)));
BSSGP.send(t_BSSGP_DL_UD(g_mmctx.tlli, llc));
BSSGP.send(ts_BSSGP_DL_UD(g_mmctx.tlli, enc_LlcPdu(llc)));
}
function f_bssgp_establish() runs on dummy_CT {
@ -257,13 +175,13 @@ module Test {
f_bssgp_establish();
BSSGP.send(t_BSSGP_PS_PAGING_IMSI(bvci, imsi));
BSSGP.send(t_BSSGP_PS_PAGING_PTMSI(bvci, imsi, tmsi));
BSSGP.send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
BSSGP.send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, tmsi));
while (true) {
var BssgpPdu pdu;
var PDU_BSSGP pdu;
alt {
[] BSSGP.receive(BssgpPdu:?) -> value pdu {
[] BSSGP.receive(PDU_BSSGP:?) -> value pdu {
log("BSSGP Rx: ", pdu);
}
[] BSSGP.receive(t_BssgpStsInd(?, ?, BVC_S_UNBLOCKED)) { repeat; }
@ -404,7 +322,7 @@ uint3_t usf) := {
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});
/* ensure that this LLC-PDU arrives from the right TLLI at the (simulated) SGSN */
BSSGP.receive(t_BSSGP_UL_UD(tlli, ?, payload));
BSSGP.receive(tr_BSSGP_UL_UD(tlli, ?, payload));
/* ensure the MS eceives an UL_ACK_NACK */
alt {
@ -428,11 +346,11 @@ uint3_t usf) := {
f_single_ul_block(CS1);
while (true) {
var BssgpPdu pdu;
var PDU_BSSGP pdu;
var RLCMAC_ph_data_ind dl_msg;
alt {
[] BSSGP.receive(BssgpPdu:?) -> value pdu {
[] BSSGP.receive(PDU_BSSGP:?) -> value pdu {
log("BSSGP Rx: ", pdu);
}
[] BSSGP.receive(t_BssgpStsInd(?, ?, BVC_S_UNBLOCKED)) { repeat; }
@ -451,12 +369,12 @@ uint3_t usf) := {
f_bssgp_establish();
while (true) {
var BssgpPdu pdu;
var PDU_BSSGP pdu;
alt {
[] BSSGP.receive(BssgpPdu:?) -> value pdu {
[] BSSGP.receive(PDU_BSSGP:?) -> value pdu {
log("BSSGP Rx: ", pdu);
//log("GMM Rx: ", dec_PDU_L3_MS_SGSN(pdu.payload));
g_mmctx.tlli := pdu.u.ul_unitdata.tlli;
g_mmctx.tlli := oct2int(pdu.pDU_BSSGP_UL_UNITDATA.tLLI);
tx_gmm(LLC_CR_DL_CMD, gmm_auth_req);
}
[] BSSGP.receive(t_BssgpStsInd(?, ?, BVC_S_UNBLOCKED)) { repeat; }
@ -494,7 +412,7 @@ uint3_t usf) := {
f_llc_dec_and_log(c_gmm_att_pcu);
f_llc_assert(f_LLC_append_fcs(c_gmm_att_pcu_nofcs), c_gmm_att_pcu);
//f_llc_assert(f_LLC_append_fcs(c_gmm_att_pcu_nofcs), c_gmm_att_pcu);
log(valueof(t_LLC_UI(LLC_CR_DL_CMD, g_mmctx.n_u, gmm_auth_req, LLC_SAPI_GMM)));
log(t_LLC_UI(LLC_CR_DL_CMD, g_mmctx.n_u, gmm_auth_req, LLC_SAPI_GMM));

View File

@ -31,8 +31,17 @@ DIR=$BASEDIR/titan.TestPorts.UNIX_DOMAIN_SOCKETasp/src
FILES="UD_PT.cc UD_PT.hh UD_PortType.ttcn UD_Types.ttcn"
gen_links $DIR $FILES
DIR=$BASEDIR/titan.ProtocolModules.NS_v7.3.0/src
FILES="NS_Types.ttcn"
gen_links $DIR $FILES
DIR=$BASEDIR/titan.ProtocolModules.BSSGP_v13.0.0/src
FILES="BSSGP_EncDec.cc BSSGP_Types.ttcn"
gen_links $DIR $FILES
DIR=../library
FILES="General_Types.ttcn GSM_Types.ttcn GSM_RR_Types.ttcn Osmocom_Types.ttcn RLCMAC_Types.ttcn RLCMAC_CSN1_Types.ttcn RLCMAC_EncDec.cc L1CTL_Types.ttcn L1CTL_PortType.ttcn LAPDm_RAW_PT.ttcn LAPDm_Types.ttcn "
FILES+="NS_Types.ttcn NS_Emulation.ttcn NS_CodecPort.ttcn NS_CodecPort_CtrlFunct.ttcn NS_CodecPort_CtrlFunctDef.cc "
FILES+="BSSGP_Emulation.ttcn BSSGP_Helper.cc BSSGP_Helper_Functions.ttcn BSSGP_Types.ttcn "
FILES+="NS_Emulation.ttcn NS_CodecPort.ttcn NS_CodecPort_CtrlFunct.ttcn NS_CodecPort_CtrlFunctDef.cc "
FILES+="BSSGP_Emulation.ttcn Osmocom_Gb_Types.ttcn "
gen_links $DIR $FILES

View File

@ -1,5 +1,5 @@
#!/bin/sh
FILES="*.ttcn BSSGP_Helper.cc IPL4asp_PT.cc IPL4asp_discovery.cc TCCConversion.cc TCCInterface.cc NS_CodecPort_CtrlFunctDef.cc UD_PT.cc RLCMAC_EncDec.cc"
FILES="*.ttcn BSSGP_EncDec.cc IPL4asp_PT.cc IPL4asp_discovery.cc TCCConversion.cc TCCInterface.cc NS_CodecPort_CtrlFunctDef.cc UD_PT.cc RLCMAC_EncDec.cc"
../regen-makefile.sh Test.ttcn $FILES

View File

@ -2,7 +2,7 @@ module BSSGP_Emulation {
import from NS_Types all;
import from NS_Emulation all;
import from BSSGP_Types all;
import from BSSGP_Helper_Functions all;
import from Osmocom_Gb_Types all;
import from IPL4asp_Types all;
type record BssgpStatusIndication {
@ -24,8 +24,8 @@ module BSSGP_Emulation {
/* port from our (internal) point of view */
type port BSSGP_SP_PT message {
in BssgpPdu;
out BssgpPdu,
in PDU_BSSGP;
out PDU_BSSGP,
NsStatusIndication,
BssgpStatusIndication,
ASP_Event;
@ -36,8 +36,8 @@ module BSSGP_Emulation {
in ASP_Event,
NsStatusIndication,
BssgpStatusIndication,
BssgpPdu;
out BssgpPdu;
PDU_BSSGP;
out PDU_BSSGP;
} with { extension "internal" };
function BssgpStart() runs on BSSGP_CT {
@ -65,10 +65,10 @@ module BSSGP_Emulation {
modulepar {
Nsvci mp_nsei := 96;
Nsvci mp_bvci := 196;
BssgpCellId mp_cellid := { ra_id := { lai := { mcc_mnc := '262F42'H, lac := 13135}, rac := 0 }, cell_id := 20960 };
BssgpCellId mp_cellid := { ra_id := { lai := { mcc_mnc := '26242F'H, lac := 13135}, rac := 0 }, cell_id := 20960 };
};
function f_BnsUdReq(template BssgpPdu pdu, BssgpBvci bvci := mp_bvci) return NsUnitdataRequest {
function f_BnsUdReq(template PDU_BSSGP pdu, BssgpBvci bvci := mp_bvci) return NsUnitdataRequest {
var NsUnitdataRequest udr := {
bvci := bvci,
nsei := mp_nsei,
@ -76,13 +76,13 @@ module BSSGP_Emulation {
* unbound integer value." when trying to send the reocrd rather than the octetstring */
//sdu := omit,
//bssgp := valueof(pdu)
sdu := f_BSSGP_compact_len(enc_BssgpPdu(valueof(pdu))),
sdu := enc_PDU_BSSGP(valueof(pdu)),
bssgp := omit
}
return udr;
}
function f_BnsUdInd(template BssgpPdu pdu, template BssgpBvci bvci := mp_bvci) return template NsUnitdataIndication {
function f_BnsUdInd(template PDU_BSSGP pdu, template BssgpBvci bvci := mp_bvci) return template NsUnitdataIndication {
var template NsUnitdataIndication udi := {
bvci := bvci,
nsei := mp_nsei,
@ -99,9 +99,9 @@ module BSSGP_Emulation {
}
private function f_sendReset() runs on BSSGP_CT {
var BssgpPdu pdu := valueof(t_BVC_RESET(BSSGP_CAUSE_OM_INTERVENTION, mp_bvci, mp_cellid));
var PDU_BSSGP pdu := valueof(ts_BVC_RESET(BSSGP_CAUSE_OM_INTERVENTION, mp_bvci, mp_cellid));
log("PDU: ", pdu);
log("ENC: ", enc_BssgpPdu(pdu));
log("ENC: ", enc_PDU_BSSGP(pdu));
/* BVC-RESET is always sent via the SIGNALLING BVCI, see Table 5.4.1 */
BSCP.send(f_BnsUdReq(pdu, 0));
@ -119,9 +119,9 @@ module BSSGP_Emulation {
g_T1.start;
}
private function f_sendStatus(BssgpCause cause, BssgpPdu pdu) runs on BSSGP_CT {
private function f_sendStatus(BssgpCause cause, PDU_BSSGP pdu) runs on BSSGP_CT {
/* FIXME: Make sure correct Signaling or PTP BVCI is used! */
BSCP.send(f_BnsUdReq(t_BSSGP_STATUS({ t_BSSGP_IE_Cause(cause), t_BSSGP_IE_Bvci(mp_bvci), t_BSSGP_IE_PDU(pdu)})));
BSCP.send(f_BnsUdReq(ts_BSSGP_STATUS(mp_bvci, cause, pdu)));
}
altstep as_allstate() runs on BSSGP_CT {
@ -136,20 +136,20 @@ module BSSGP_Emulation {
}
/* Respond to RESET with correct BVCI/CellID */
[] BSCP.receive(f_BnsUdInd(t_BVC_RESET(?, mp_bvci, mp_cellid), 0)) -> value udi {
[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, mp_bvci, mp_cellid), 0)) -> value udi {
log("Rx BVC-RESET for Our BVCI=", mp_bvci);
BSCP.send(f_BnsUdReq(t_BVC_RESET_ACK(mp_bvci, mp_cellid), 0));
BSCP.send(f_BnsUdReq(ts_BVC_RESET_ACK(mp_bvci, mp_cellid), 0));
f_change_state(BVC_S_UNBLOCKED);
}
/* Respond to RESET for signalling BVCI 0 */
[] BSCP.receive(f_BnsUdInd(t_BVC_RESET(?, 0, mp_cellid), 0)) -> value udi {
[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, 0, mp_cellid), 0)) -> value udi {
log("Rx BVC-RESET for Signaling BVCI=0");
BSCP.send(f_BnsUdReq(t_BVC_RESET_ACK(0, mp_cellid), 0));
BSCP.send(f_BnsUdReq(ts_BVC_RESET_ACK(0, mp_cellid), 0));
}
/* Respond to RESET with wrong NSEI/NSVCI */
[] BSCP.receive(f_BnsUdInd(t_BVC_RESET(?, ?, ?), 0)) -> value udi {
[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, ?, ?), 0)) -> value udi {
log("Rx BVC-RESET for unknown BVCI");
f_sendStatus(BSSGP_CAUSE_BVCI_UNKNOWN, udi.bssgp);
}
@ -175,11 +175,11 @@ module BSSGP_Emulation {
private function f_ScanEvents() runs on BSSGP_CT {
var NsUnitdataIndication udi;
var BssgpPdu bs_pdu;
var PDU_BSSGP bs_pdu;
var default d;
log("matching against ", t_BVC_RESET(?, mp_bvci, mp_cellid));
log("matching against ", tr_BVC_RESET(?, mp_bvci, mp_cellid));
d := activate(as_allstate());
@ -213,28 +213,30 @@ module BSSGP_Emulation {
g_T1.stop;
f_change_state(BVC_S_BLOCKED);
}
[] BSCP.receive(f_BnsUdInd(t_BVC_RESET_ACK(mp_bvci, mp_cellid), 0)) -> value udi {
[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET_ACK(mp_bvci, mp_cellid), 0)) -> value udi {
g_T2.stop;
f_change_state(BVC_S_UNBLOCKED);
}
/* simply acknowledge all Flow Control Messages */
/*
[g_sgsn_role] BSCP.receive(f_BnsUdInd(t_BVC_FC_BVC)) {
BSCP.send(f_BnsUdReq(t_BVC_FC_BVC_ACK));
}
[g_sgsn_role] BSCP.receive(f_BnsUdInd(t_BVC_FC_MS)) {
BSCP.send(f_BnsUdReq(t_BVC_FC_MS_ACK));
}
*/
/* BSSGP-UNITDATA PDUs from network to NS-UNITDATA.ind to user */
[] BSCP.receive(f_BnsUdInd(tr_BSSGP_type(DL_UNITDATA))) -> value udi {
[not g_sgsn_role] BSCP.receive(f_BnsUdInd(tr_BSSGP_DL_UD)) -> value udi {
BSSGP_SP.send(udi.bssgp);
}
[] BSCP.receive(f_BnsUdInd(tr_BSSGP_type(UL_UNITDATA))) -> value udi {
[g_sgsn_role] BSCP.receive(f_BnsUdInd(tr_BSSGP_UL_UD)) -> value udi {
BSSGP_SP.send(udi.bssgp);
}
/* pass virtually any PDU from user to NS-UNITDATA PDU on network */
[] BSSGP_SP.receive(BssgpPdu:?) -> value bs_pdu {
[] BSSGP_SP.receive(PDU_BSSGP:?) -> value bs_pdu {
BSCP.send(f_BnsUdReq(bs_pdu));
}

View File

@ -2,7 +2,6 @@ module NS_CodecPort {
import from IPL4asp_PortType all;
import from IPL4asp_Types all;
import from BSSGP_Helper_Functions all;
import from NS_Types all;
type record NS_RecvFrom {
@ -11,10 +10,10 @@ module NS_CodecPort {
PortNumber remPort,
HostName locName,
PortNumber locPort,
NsPdu msg
PDU_NS msg
}
template NS_RecvFrom t_NS_RecvFrom(template NsPdu pdu) := {
template NS_RecvFrom t_NS_RecvFrom(template PDU_NS pdu) := {
connId := ?,
remName := ?,
remPort := ?,
@ -25,10 +24,10 @@ module NS_CodecPort {
type record NS_Send {
ConnectionId connId,
NsPdu msg
PDU_NS msg
}
template NS_Send t_NS_Send(template ConnectionId connId, template NsPdu msg) := {
template NS_Send t_NS_Send(template ConnectionId connId, template PDU_NS msg) := {
connId := connId,
msg := msg
}
@ -39,13 +38,13 @@ module NS_CodecPort {
pout.remPort := pin.remPort;
pout.locName := pin.locName;
pout.locPort := pin.locPort;
pout.msg := dec_NsPdu(f_NS_expand_len(pin.msg));
pout.msg := dec_PDU_NS(pin.msg);
} with { extension "prototype(fast)" };
private function NS_to_IPL4_Send(in NS_Send pin, out ASP_Send pout) {
pout.connId := pin.connId;
pout.proto := { udp := {} };
pout.msg := f_NS_compact_len(enc_NsPdu(pin.msg));
pout.msg := enc_PDU_NS(pin.msg);
} with { extension "prototype(fast)" };
type port NS_CODEC_PT message {

View File

@ -1,7 +1,7 @@
module NS_Emulation {
import from NS_Types all;
import from BSSGP_Types all;
import from BSSGP_Helper_Functions all;
import from Osmocom_Gb_Types all;
import from NS_CodecPort all;
import from NS_CodecPort_CtrlFunct all;
import from IPL4asp_Types all;
@ -10,11 +10,11 @@ module NS_Emulation {
BssgpBvci bvci,
Nsei nsei,
octetstring sdu optional,
BssgpPdu bssgp optional
PDU_BSSGP bssgp optional
}
template NsUnitdataRequest t_NsUdReq(template Nsei nsei, template BssgpBvci bvci, template octetstring sdu,
template BssgpPdu bssgp) := {
template PDU_BSSGP bssgp) := {
bvci := bvci,
nsei := nsei,
sdu := sdu,
@ -25,14 +25,14 @@ module NS_Emulation {
BssgpBvci bvci,
Nsei nsei,
octetstring sdu optional,
BssgpPdu bssgp optional
PDU_BSSGP bssgp optional
}
template NsUnitdataIndication t_NsUdInd(Nsei nsei, BssgpBvci bvci, octetstring sdu) := {
bvci := bvci,
nsei := nsei,
sdu := sdu,
bssgp := dec_BssgpPdu(f_BSSGP_expand_len(sdu))
bssgp := dec_PDU_BSSGP(sdu)
}
type record NsStatusIndication {
@ -186,7 +186,7 @@ module NS_Emulation {
/* default case of handling unknown PDUs */
[] NSCP.receive(t_NS_RecvFrom(?)) -> value rf {
log("Rx Unexpected NS PDU ", rf.msg," in state ", g_state);
NSCP.send(t_NS_Send(g_conn_id, t_NS_STATUS(NS_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE, rf.msg)));
NSCP.send(t_NS_Send(g_conn_id, ts_NS_STATUS(NS_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE, rf.msg)));
}
/* Forwarding of ASP_Evet to user */
[] NSCP.receive(ASP_Event:?) -> value evt { NS_SP.send(evt); }
@ -250,7 +250,9 @@ module NS_Emulation {
}
/* NS-UNITDATA PDU from network to NS-UNITDATA.ind to user */
[] NSCP.receive(t_NS_RecvFrom(t_NS_UNITDATA(?, ?, ?))) -> value rf {
NS_SP.send(t_NsUdInd(mp_nsei, rf.msg.u.unitdata.bvci, rf.msg.u.unitdata.sdu));
NS_SP.send(t_NsUdInd(mp_nsei,
oct2int(rf.msg.pDU_NS_Unitdata.bVCI),
rf.msg.pDU_NS_Unitdata.nS_SDU));
}
/* NS-UNITDATA.req from user to NS-UNITDATA PDU on network */
[] NS_SP.receive(t_NsUdReq(mp_nsei, ?, ?, omit)) -> value ud_req {
@ -259,7 +261,7 @@ module NS_Emulation {
}
[] NS_SP.receive(t_NsUdReq(mp_nsei, ?, omit, ?)) -> value ud_req {
/* using decoded BSSGP PDU that we need to encode first */
var octetstring enc := f_BSSGP_compact_len(enc_BssgpPdu(ud_req.bssgp));
var octetstring enc := enc_PDU_BSSGP(ud_req.bssgp);
NSCP.send(t_NS_Send(g_conn_id, t_NS_UNITDATA(t_SduCtrlB, ud_req.bvci, enc)));
}
}

View File

@ -0,0 +1,664 @@
module Osmocom_Gb_Types {
/* This module contains additional definitions and templates that we use on top of the
* TITAN NS + BSSGP modules */
import from General_Types all;
import from Osmocom_Types all;
import from GSM_Types all;
import from GSM_RR_Types all;
import from BSSGP_Types all
import from NS_Types all
type uint16_t Nsvci;
type uint16_t Nsei;
type uint16_t BssgpBvci;
/* TS 48.016 10.3.7 */
type enumerated NsPduType {
NS_PDUT_NS_UNITDATA ('00000000'B),
NS_PDUT_NS_RESET ('00000010'B),
NS_PDUT_NS_RESET_ACK ('00000011'B),
NS_PDUT_NS_BLOCK ('00000100'B),
NS_PDUT_NS_BLOCK_ACK ('00000101'B),
NS_PDUT_NS_UNBLOCK ('00000110'B),
NS_PDUT_NS_UNBLOCK_ACK ('00000111'B),
NS_PDUT_NS_STATUS ('00001000'B),
NS_PDUT_NS_ALIVE ('00001010'B),
NS_PDUT_NS_ALIVE_ACK ('00001011'B)
/* FIXME: SNS */
} with { variant "FIELDLENGTH(8)" };
/* TS 48.016 10.3 */
type enumerated NsIEI {
NS_IEI_CAUSE ('00000000'B),
NS_IEI_NSVCI ('00000001'B),
NS_IEI_NS_PDU ('00000010'B),
NS_IEI_BVCI ('00000011'B),
NS_IEI_NSEI ('00000100'B),
NS_IEI_LIST_IPv4 ('00000101'B),
NS_IEI_LIST_IPv6 ('00000110'B),
NS_IEI_MAX_NUM_NSVC ('00000111'B),
NS_IEI_NUM_IPv4_EP ('00001000'B),
NS_IEI_NUM_IPv6_EP ('00001001'B),
NS_IEI_RESET_FLAG ('00001010'B),
NS_IEI_IP_ADDRESS ('00001011'B)
} with { variant "FIELDLENGTH(8)" };
/* TS 48.016 10.3.2 */
type enumerated NsCause {
NS_CAUSE_TRANSIT_NETWORK_FAILURE ('00000000'B),
NS_CAUSE_OM_INTERVENTION ('00000001'B),
NS_CAUSE_EQUIPMENT_FAILURE ('00000010'B),
NS_CAUSE_NSVC_BLOCKED ('00000011'B),
NS_CAUSE_NSVC_UNKNOWN ('00000100'B),
NS_CAUSE_BVCI_UNKNOWN_AT_NSE ('00000101'B),
NS_CAUSE_SEMANTICALLY_INCORRECT_PDU ('00001000'B),
NS_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE ('00001010'B),
NS_CAUSE_PROTOCOL_ERROR_UNSPEIFIED ('00001011'B),
NS_CAUSE_INVALID_ESSENTIAL_IE ('00001100'B),
NS_CAUSE_MISSING_ESSENTIAL_IE ('00001101'B),
NS_CAUSE_INVALID_NR_OF_IPv4_ENDPOINTS ('00001110'B),
NS_CAUSE_INVALID_NR_OF_IPv6_ENDPOINTS ('00001111'B),
NS_CAUSE_INVALID_NR_OF_NSVCS ('00010000'B),
NS_CAUSE_INVALID_WEIGHTS ('00010001'B),
NS_CAUSE_UNKNOWN_IP_ENDPOINT ('00010010'B),
NS_CAUSE_UNKNOWN_IP_ADDRESS ('00010011'B),
NS_CAUSE_IP_TEST_FAILEDA ('00010100'B)
} with { variant "FIELDLENGTH(8)" };
template NS_SDU_ControlBits t_SduCtrlB := {
rBit := '0'B,
cBit := '0'B,
spare := '000000'B
}
function t_NS_IE_CAUSE(template NsCause cause) return template CauseNS {
var template CauseNS ret;
ret.iEI := '00'O;
ret.ext := '1'B;
ret.lengthIndicator := { length1 := 1 };
if (isvalue(cause)) {
ret.cause := int2oct(enum2int(valueof(cause)), 1);
} else {
ret.cause := ?
}
return ret;
}
private function f_oct_or_wc(template integer inp, integer len) return template octetstring {
if (isvalue(inp)) {
return int2oct(valueof(inp), len);
} else {
return ?
}
}
template NS_VCI t_NS_IE_NSVCI(template Nsvci nsvci) := {
iEI := '01'O,
ext := '1'B,
lengthIndicator := {
length1 := 2
},
nS_VCI := f_oct_or_wc(nsvci, 2)
}
template NSEI_NS t_NS_IE_NSEI(template Nsei nsei) := {
iEI:= '04'O,
ext := '1'B,
lengthIndicator := {
length1 := 2
},
nSEI := f_oct_or_wc(nsei, 2)
}
template PDU_NS t_NS_RESET(template NsCause cause, template Nsvci nsvci, template Nsei nsei) := {
pDU_NS_Reset := {
nsPduType := '02'O,
causeNS := t_NS_IE_CAUSE(cause),
nS_VCI := t_NS_IE_NSVCI(nsvci),
nSEI_NS := t_NS_IE_NSEI(nsei)
}
}
template PDU_NS t_NS_RESET_ACK(template Nsvci nsvci, template Nsei nsei) := {
pDU_NS_Reset_Ack := {
nsPduType := '03'O,
nS_VCI := t_NS_IE_NSVCI(nsvci),
nSEI_NS := t_NS_IE_NSEI(nsei)
}
}
template PDU_NS t_NS_BLOCK(template NsCause cause, template Nsvci nsvci) := {
pDU_NS_Block := {
nsPduType := '04'O,
causeNS := t_NS_IE_CAUSE(cause),
nS_VCI := t_NS_IE_NSVCI(nsvci)
}
}
template PDU_NS t_NS_BLOCK_ACK(template Nsvci nsvci) := {
pDU_NS_Block_Ack := {
nsPduType := '05'O,
nS_VCI := t_NS_IE_NSVCI(nsvci)
}
}
template PDU_NS t_NS_UNBLOCK := {
pDU_NS_Unblock := {
nsPduType := '06'O
}
}
template PDU_NS t_NS_UNBLOCK_ACK := {
pDU_NS_Unblock_Ack := {
nsPduType := '07'O
}
}
template PDU_NS t_NS_ALIVE := {
pDU_NS_Alive := {
nsPduType := '0A'O
}
}
template PDU_NS t_NS_ALIVE_ACK := {
pDU_NS_Alive_Ack := {
nsPduType := '0B'O
}
}
template PDU_NS ts_NS_STATUS(NsCause cause, PDU_NS pdu) := {
pDU_NS_Status := {
nsPduType := '08'O,
causeNS := t_NS_IE_CAUSE(cause),
nS_VCI := omit,
nS_PDU := {
iEI := '02'O,
ext := '1'B,
lengthIndicator := {
length1 := 0 /* overwritten */
},
ns_PDU := enc_PDU_NS(pdu)
},
bVCI_NS := omit,
listofIP4Elements := omit,
listofIP6Elements := omit
}
}
template PDU_NS t_NS_UNITDATA(template NS_SDU_ControlBits bits, template BssgpBvci bvci, template
octetstring sdu) := {
pDU_NS_Unitdata := {
nsPduType := '00'O,
nS_SDU_ControlBits := bits,
bVCI := f_oct_or_wc(bvci, 2),
nS_SDU := sdu
}
}
type record BssgpCellId {
RoutingAreaIdentification ra_id,
CellIdentity cell_id
} with { variant "" };
type enumerated BssgpCause {
BSSGP_CAUSE_PROC_OVERLOAD ('00'H),
BSSGP_CAUSE_EQUIMENT_FAILURE ('01'H),
BSSGP_CAUSE_TRANSIT_NETWORK_FAILURE ('02'H),
BSSGP_CAUSE_NET_SV_CAP_MOD_GT_ZERO_KBPS ('03'H),
BSSGP_CAUSE_UNKNOWN_MS ('04'H),
BSSGP_CAUSE_BVCI_UNKNOWN ('05'H),
BSSGP_CAUSE_CELL_TRAFFIC_CONGESTION ('06'H),
BSSGP_CAUSE_SGSN_CONGESTION ('07'H),
BSSGP_CAUSE_OM_INTERVENTION ('08'H),
BSSGP_CAUSE_BVCI_BLOCKED ('09'H),
BSSGP_CAUSE_PFC_CREATE_FAILURE ('0a'H),
BSSGP_CAUSE_PFC_PREEMPTED ('0b'H),
BSSGP_CAUSE_ABQP_NO_MORE_SUPPORTED ('0c'H),
BSSGP_CAUSE_SEMANTICALLY_INCORRECT_PDU ('20'H),
BSSGP_CAUSE_INVALID_MANDATORY_IE ('21'H),
BSSGP_CAUSE_MISSING_MANDATORY_IE ('22'H),
BSSGP_CAUSE_MISSING_CONDITIONAL_IE ('23'H),
BSSGP_CAUSE_UNEXPECTED_CONDITIONAL_IE ('24'H),
BSSGP_CAUSE_CONDITIONAL_IE_ERROR ('25'H),
BSSGP_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE ('26'H),
BSSGP_CAUSE_PROTOCOL_ERROR_UNSPECIFIED ('27'H),
BSSGP_CAUSE_PDU_NOT_COMPATIBLE_WITH_FEATURE_SET ('28'H),
BSSGP_CAUSE_REQUESTED_INFO_NOT_AVAILABLE ('29'H),
BSSGP_CAUSE_UNKNOWN_DESTINATION_ADDRESS ('2a'H),
BSSGP_CAUSE_UNKNOWN_RIM_APP_IDENTITY ('2b'H),
BSSGP_CAUSE_INVALID_CONTAINER_UNIT_INFO ('2c'H),
BSSGP_CAUSE_PFC_QUEUING ('2d'H),
BSSGP_CAUSE_PFC_CREATED_SUCCESSFULLY ('2e'H),
BSSGP_CAUSE_T12_EXPIRY ('2f'H),
BSSGP_CAUSE_MS_UNDER_PS_HANDOVER_TREATMENT ('30'H),
BSSGP_CAUSE_UPLINK_QUALITY ('31'H),
BSSGP_CAUSE_UPLINK_STRENGTH ('32'H),
BSSGP_CAUSE_DOWNLINK_QUALITY ('33'H),
BSSGP_CAUSE_DOWNLINK_STRENGTH ('34'H),
BSSGP_CAUSE_DISTANCE ('35'H),
BSSGP_CAUSE_BETTER_CELL ('36'H),
BSSGP_CAUSE_TRAFFIC ('37'H),
BSSGP_CAUSE_OM_INTERVENTION2 ('38'H),
BSSGP_CAUSE_MS_BACK_ON_OLD_CHANNEL ('39'H),
BSSGP_CAUSE_T13_EXPIRY ('3a'H),
BSSGP_CAUSE_T14_EXPIRY ('3b'H),
BSSGP_CAUSE_NOT_ALL_REQUESTED_PFC_CREATED ('3c'H)
} with { variant "FIELDLENGTH(8)" };
template BVCI t_BSSGP_BVCI(template BssgpBvci bvci) := {
iEI := '04'O,
ext := '1'B,
lengthIndicator := {
length1 := 2
},
unstructured_value := f_oct_or_wc(bvci, 2)
}
template IMSI_BSSGP tr_BSSGP_IMSI(template hexstring imsi) := {
iEI := '0D'O,
ext := '1'B,
lengthIndicator := ?,
type_of_Identity := '001'B,
oddevenIndicator := ?,
digits := imsi
}
template IMSI_BSSGP ts_BSSGP_IMSI(hexstring imsi) := {
iEI := '0D'O,
ext := '1'B,
lengthIndicator := { length1 := 0 /* overwritten */ },
type_of_Identity := '001'B,
oddevenIndicator := f_hex_is_odd_length(imsi),
digits := imsi
}
template TMSI_BSSGP ts_BSSGP_TMSI(GsmTmsi tmsi) := {
iEI := '20'O,
ext := '1'B,
lengthIndicator := { length1 := 4 },
tMSI_Value := int2oct(tmsi, 4)
}
function f_bssgp_length_ind(integer len) return LIN2_2a {
var LIN2_2a ret;
if (len > 255) {
ret := { length2 := len };
} else {
ret := { length1 := len };
}
return ret;
}
template LLC_PDU ts_BSSGP_LLC_PDU(octetstring pdu) := {
iEI := '0D'O,
ext := '1'B,
lengthIndicator := f_bssgp_length_ind(lengthof(pdu)),
lLC_PDU := pdu
}
template LLC_PDU tr_BSSGP_LLC_PDU(template octetstring pdu := ?) := {
iEI := '0D'O,
ext := '1'B,
lengthIndicator := ?,
lLC_PDU := pdu
}
function t_BSSGP_CAUSE(template BssgpCause cause) return template Cause_BSSGP {
var template Cause_BSSGP ret;
ret.iEI := '08'O;
ret.ext := '1'B;
ret.lengthIndicator := { length1 := 1 };
if (isvalue(cause)) {
ret.cause_Value := int2oct(enum2int(valueof(cause)), 1);
} else {
ret.cause_Value := ?
}
return ret;
}
function t_BSSGP_IE_CellId(template BssgpCellId cid) return template Cell_Identifier {
var template Cell_Identifier ret := {
iEI := '08'O,
ext := '1'B,
lengthIndicator := { length1 := 8 },
mccDigit1 := ?,
mccDigit2 := ?,
mccDigit3 := ?,
mncDigit3 := ?,
mncDigit1 := ?,
mncDigit2 := ?,
lac := ?,
rac := ?,
cI_value := ?
}
if (istemplatekind(cid, "omit")) {
return omit;
} else if (istemplatekind(cid, "*")) {
return *;
} else if (istemplatekind(cid, "?")) {
return ?;
}
if (isvalue(cid) and isvalue(cid.ra_id) and isvalue(cid.ra_id.lai)) {
if (isvalue(cid.ra_id.lai.mcc_mnc)) {
ret.mccDigit1 := cid.ra_id.lai.mcc_mnc[0];
ret.mccDigit2 := cid.ra_id.lai.mcc_mnc[1];
ret.mccDigit3 := cid.ra_id.lai.mcc_mnc[2];
ret.mncDigit3 := cid.ra_id.lai.mcc_mnc[5];
ret.mncDigit2 := cid.ra_id.lai.mcc_mnc[4];
ret.mncDigit1 := cid.ra_id.lai.mcc_mnc[3];
}
if (isvalue(cid.ra_id.lai.lac)) {
ret.lac := f_oct_or_wc(cid.ra_id.lai.lac, 2);
}
}
if (isvalue(cid) and isvalue(cid.ra_id)) {
ret.rac := f_oct_or_wc(cid.ra_id.rac, 1);
}
if (isvalue(cid)) {
ret.cI_value := f_oct_or_wc(cid.cell_id, 2);
}
return ret;
}
template PDU_BSSGP ts_BVC_RESET(BssgpCause cause, BssgpBvci bvci,
template BssgpCellId cell_id) := {
pDU_BSSGP_BVC_RESET := {
bssgpPduType := '22'O,
bVCI := t_BSSGP_BVCI(bvci),
cause := t_BSSGP_CAUSE(cause),
cell_Identifier := t_BSSGP_IE_CellId(cell_id),
feature_bitmap := omit,
extended_Feature_Bitmap := omit
}
}
template PDU_BSSGP tr_BVC_RESET(template BssgpCause cause, template BssgpBvci bvci,
template BssgpCellId cell_id) := {
pDU_BSSGP_BVC_RESET := {
bssgpPduType := '22'O,
bVCI := t_BSSGP_BVCI(bvci),
cause := t_BSSGP_CAUSE(cause),
cell_Identifier := t_BSSGP_IE_CellId(cell_id),
feature_bitmap := *,
extended_Feature_Bitmap := *
}
}
template PDU_BSSGP ts_BVC_RESET_ACK(BssgpBvci bvci, template BssgpCellId cell_id) := {
pDU_BSSGP_BVC_RESET_ACK := {
bssgpPduType := '23'O,
bVCI := t_BSSGP_BVCI(bvci),
cell_Identifier := t_BSSGP_IE_CellId(cell_id),
feature_bitmap := omit,
extended_Feature_Bitmap := omit
}
}
template PDU_BSSGP tr_BVC_RESET_ACK(template BssgpBvci bvci, template BssgpCellId cell_id) := {
pDU_BSSGP_BVC_RESET_ACK := {
bssgpPduType := '23'O,
bVCI := t_BSSGP_BVCI(bvci),
cell_Identifier := t_BSSGP_IE_CellId(cell_id),
feature_bitmap := *,
extended_Feature_Bitmap := *
}
}
template PDU_BSSGP t_BVC_UNBLOCK(template BssgpBvci bvci) := {
pDU_BSSGP_BVC_UNBLOCK := {
bssgpPduType := '24'O,
bVCI := t_BSSGP_BVCI(bvci)
}
}
template PDU_BSSGP t_BVC_UNBLOCK_ACK(template BssgpBvci bvci) := {
pDU_BSSGP_BVC_UNBLOCK_ACK := {
bssgpPduType := '25'O,
bVCI := t_BSSGP_BVCI(bvci)
}
}
template PDU_BSSGP t_BVC_BLOCK(template BssgpBvci bvci, template BssgpCause cause) := {
pDU_BSSGP_BVC_BLOCK := {
bssgpPduType := '20'O,
bVCI := t_BSSGP_BVCI(bvci),
cause := t_BSSGP_CAUSE(cause)
}
}
template PDU_BSSGP t_BVC_BLOCK_ACK(template BssgpBvci bvci) := {
pDU_BSSGP_BVC_BLOCK_ACK := {
bssgpPduType := '21'O,
bVCI := t_BSSGP_BVCI(bvci)
}
}
template PDU_BSSGP t_BVC_FC_BVC(uint16_t bmax, uint16_t bucket_leak_rate,
uint16_t bmax_default_ms, uint16_t r_default_ms, OCT1 tag) := {
pDU_BSSGP_FLOW_CONTROL_BVC := {
bssgpPduType := '26'O,
tag := {
iEI := '1E'O,
ext := '1'B,
lengthIndicator := {
length1 := 2
},
unstructured_Value := tag
},
bVC_Bucket_Size := {
iEI := '05'O,
ext := '1'B,
lengthIndicator := {
length1 := 2
},
bmax := f_oct_or_wc(bmax, 2)
},
bucket_Leak_Rate := {
iEI := '03'O,
ext := '1'B,
lengthIndicator := {
length1 := 1
},
r_Value := f_oct_or_wc(bucket_leak_rate, 2)
},
bmax_default_MS := {
iEI := '01'O,
ext := '1'B,
lengthIndicator := {
length1 := 2
},
bmax := f_oct_or_wc(bmax_default_ms, 2)
},
r_default_MS := {
iEI := '1C'O,
ext := '1'B,
lengthIndicator := {
length1 := 2
},
r_default_MS_value := f_oct_or_wc(r_default_ms, 2)
},
bucket_Full_Ratio := omit,
bVC_Measurement := omit,
flow_Control_Granularity := omit
}
}
template PDU_BSSGP t_BVC_FC_BVC_ACK(template OCT1 tag) := {
pDU_BSSGP_FLOW_CONTROL_BVC_ACK := {
bssgpPduType := '27'O,
tag := {
iEI := '1E'O,
ext := '1'B,
lengthIndicator := {
length1 := 2
},
unstructured_Value := tag
}
}
}
template PDU_BSSGP ts_BSSGP_STATUS(template BssgpBvci bvci, template BssgpCause cause,
PDU_BSSGP pdu) := {
pDU_BSSGP_STATUS := {
bssgpPduType := '0A'O,
cause := t_BSSGP_CAUSE(cause),
bVCI := t_BSSGP_BVCI(bvci),
pDU_in_Error := {
iEI := '15'O,
ext := '1'B,
lengthIndicator := {
length1 := 0 /* overwritten */
},
erroneous_BSSGP_PDU := enc_PDU_BSSGP(pdu)
}
}
}
template QoS_Profile_V t_defaultQos := {
peak_Bit_Rate := int2oct(80, 2),
precedence := '000'B,
a_bit := '0'B,
t_bit := '0'B,
c_r_bit := '0'B,
peakBitRateGranularity := '00'B
}
template QoS_Profile ts_QoS_TLV(template QoS_Profile_V qos) := {
iEI := '18'O,
ext := '1'B,
lengthIndicator := { length1 := 3 },
peak_Bit_Rate := qos.peak_Bit_Rate,
precedence := qos.precedence,
a_bit := qos.a_bit,
t_bit := qos.t_bit,
c_r_bit := qos.c_r_bit,
peakBitRateGranularity := qos.peakBitRateGranularity
}
template PDU_Lifetime t_DefaultLifetime(uint16_t delay := 65535) := {
iEI := '16'O,
ext := '1'B,
lengthIndicator := {
length1 := 2
},
delay_Value := f_oct_or_wc(delay, 2)
}
template PDU_BSSGP ts_BSSGP_DL_UD(GprsTlli tlli, octetstring pdu) := {
pDU_BSSGP_DL_UNITDATA := {
bssgpPduType := '00'O,
tLLI_current := f_oct_or_wc(tlli, 4),
qoS_Profile := t_defaultQos,
pDU_Lifetime := t_DefaultLifetime(65535),
mS_Radio_Access_Capability := omit,
priority := omit,
dRX_Parameters := omit,
iMSI := omit,
tLLI_old := omit,
pFI := omit,
lSA_Information := omit,
service_UTRAN_CCO := omit,
service_Class_Indicator := omit,
subscriber_Profile_ID_For_RAT_Priority := omit,
redirection_Indication := omit,
redirection_Completed := omit,
unconfirmed_Send_State_Variable := omit,
sCI := omit,
gGSN_PGW_Location := omit,
eDRX_Paremeters := omit,
old_Routing_Area_Identification := omit,
attach_Indicator := omit,
alignment_octets := omit,
lLC_PDU := ts_BSSGP_LLC_PDU(pdu),
initialLLC_PDU := omit
}
}
template PDU_BSSGP tr_BSSGP_DL_UD := {
pDU_BSSGP_DL_UNITDATA := {
bssgpPduType := '00'O,
tLLI_current := ?,
qoS_Profile := ?,
pDU_Lifetime := ?,
mS_Radio_Access_Capability := *,
priority := *,
dRX_Parameters := *,
iMSI := *,
tLLI_old := *,
pFI := *,
lSA_Information := *,
service_UTRAN_CCO := *,
service_Class_Indicator := *,
subscriber_Profile_ID_For_RAT_Priority := *,
redirection_Indication := *,
redirection_Completed := *,
unconfirmed_Send_State_Variable := *,
sCI := *,
gGSN_PGW_Location := *,
eDRX_Paremeters := *,
old_Routing_Area_Identification := *,
attach_Indicator := *,
alignment_octets := *,
lLC_PDU := tr_BSSGP_LLC_PDU,
initialLLC_PDU := *
}
}
template PDU_BSSGP tr_BSSGP_UL_UD(template GprsTlli tlli := ?, template BssgpCellId cell_id := ?,
template octetstring payload := ?) := {
pDU_BSSGP_UL_UNITDATA := {
bssgpPduType := '01'O,
tLLI := f_oct_or_wc(tlli, 4),
qoS_Profile := ?,
cell_Identifier := t_BSSGP_IE_CellId(cell_id),
pFI := *,
lSA_Identifier_List := *,
redirect_Attempt_Flag := *,
iMSI_BSSGP := *,
unconfirmed_Send_State_Variable := *,
selected_PLMN_ID := *,
selected_Operator := *,
cS_Registered_Operator := *,
alignment_octets := *,
lLC_PDU := tr_BSSGP_LLC_PDU(payload)
}
}
template PDU_BSSGP ts_BSSGP_PS_PAGING_IMSI(BssgpBvci bvci, hexstring imsi) := {
pDU_BSSGP_PAGING_PS := {
bssgpPduType := '06'O,
iMSI := ts_BSSGP_IMSI(imsi),
dRX_Parameters := omit,
paging_Field4 := {
bVCI := t_BSSGP_BVCI(bvci)
},
pFI := omit,
aBQP := omit,
qoS_Profile := ts_QoS_TLV(t_defaultQos),
pTMSI := omit,
eDRX_Paremeters := omit
}
}
template PDU_BSSGP ts_BSSGP_PS_PAGING_PTMSI(BssgpBvci bvci, hexstring imsi, GsmTmsi tmsi) := {
pDU_BSSGP_PAGING_PS := {
bssgpPduType := '06'O,
iMSI := ts_BSSGP_IMSI(imsi),
dRX_Parameters := omit,
paging_Field4 := {
bVCI := t_BSSGP_BVCI(bvci)
},
pFI := omit,
aBQP := omit,
qoS_Profile := ts_QoS_TLV(t_defaultQos),
pTMSI := ts_BSSGP_TMSI(tmsi),
eDRX_Paremeters := omit
}
}
} with { encode "RAW" };