module BSSGP_Types { /* BSSGP type definitions in TTCN-3 * (C) 2018 Harald Welte * 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 */ import from General_Types all; import from Osmocom_Types all; import from GSM_Types all; import from GSM_RR_Types all; import from L3_Templates all; import from BSSGP_Helper_Functions all; type enumerated BssgpPduType { DL_UNITDATA ('00'H), UL_UNITDATA ('01'H), RA_CAPABILITY ('02'H), DL_MBMS_UNITDATA ('04'H), UL_MBMS_UNITDATA ('05'H), /* between GMM SAPs */ PAGING_PS ('06'H), PAGING_CS ('07'H), RA_CAPABILITY_UPDATE ('08'H), RA_CAPABILITY_UPDATE_ACK ('09'H), RADIO_STATUS ('0A'H), SUSPEND ('0B'H), SUSPEND_ACK ('0C'H), SUSPEND_NACK ('0D'H), RESUME ('0E'H), RESUME_ACK ('0F'H), RESUME_NACK ('10'H), /* between NM SAPs */ BVC_BLOCK ('20'H), BVC_BLOCK_ACK ('21'H), BVC_RESET ('22'H), BVC_RESET_ACK ('23'H), BVC_UNBLOCK ('24'H), BVC_UNBLOCK_ACK ('25'H), FLOW_CONTROL_BVC ('26'H), FLOW_CONTROL_BVC_ACK ('27'H), FLOW_CONTROL_MS ('28'H), FLOW_CONTROL_MS_ACK ('29'H), FLUSH_LL ('2A'H), FLUSH_LL_ACK ('2B'H), LLC_DISCARDED ('2C'H), FLOW_CONTROL_PFC ('2D'H), FLOW_CONTROL_PFC_ACK ('2E'H), SGSN_INVOKE_TRACE ('40'H), STATUS ('41'H) /* between PFM SAPs : TODO */ /* between LCS SAPs : TODO */ /* between RIM SAPs : TODO */ /* between MBMS SAPs : TODO */ } with { variant "FIELDLENGTH(8)" }; type enumerated BssgpIEI { ALIGNMENT_OCTETS ('00'H), BMAX_DEFAULT_MS ('01'H), BSS_AREA_INDICATION ('02'H), BUCKET_LEAK_RATE ('03'H), BVCI ('04'H), BVC_BUCKET_SIZE ('05'H), BVC_MEASUREMENT ('06'H), CAUSE ('07'H), CELL_ID ('08'H), CHENNEL_NEEDED ('09'H), DRX_PARAMETERS ('0A'H), EMLPP_PRIORITY ('0B'H), FLUSH_ACTION ('0C'H), IMSI ('0D'H), LLC_PDU ('0E'H), LLC_FRAMES_DISCARDED ('0F'H), LOCATION_AREA ('10'H), MOBILE_IDENTITY ('11'H), MS_BUCKET_SIZE ('12'H), MS_RADIO_ACCESS_CAPABILITY ('13'H), OMC_ID ('14'H), PDU_IN_ERROR ('15'H), PDU_LIFETIME ('16'H), PRIORITY ('17'H), QOS_PROFILE ('18'H), RADIO_CAUSE ('19'H), RA_CAP_UPD_CAUSE ('1A'H), ROUTEING_AREA ('1B'H), R_DEFAULT_MS ('1C'H), SUSPE_DN_REFERENCE_NR ('1D'H), TAG ('1E'H), TLLI ('1F'H), TMSI ('20'H), TRACE_REFERENCE ('21'H), TRACE_TYPE ('22'H), TRANSACTION_ID ('23'H), TRIGGER_ID ('24'H), NUMBER_OF_OCTETS_AFFECTED ('25'H), LSA_IDENTIFIER_LIST ('26'H), LSA_INFORMATION ('27'H), PACKET_FLOW_IDENTIFIER ('28'H), PACKET_FLOW_TIMER ('29'H), AGGREGATE_BSS_QOS_PROFILE ('3a'H), FEATURE_BITMAP ('3b'H), BUCKET_FILL_RATIO ('3c'H), SERVICE_UTRAN_CCO ('3d'H), NSEI ('3e'H), RRLP_APDU ('3f'H), LCS_QOS ('40'H), LCS_CLIENT_TYPE ('41'H), REQUESTED_GPS_ASSIST_DATA ('42'H), LOCATION_TYPE ('43'H), LOCATION_ESTIMATE ('44'H), POSITIONING_DATA ('45'H), DECIPHERING_KEYS ('46'H), LCS_PRIORITY ('47'H), LCS_CAUSE ('48'H), LCS_CAPABILITY ('49'H), RRLP_FLAGS ('4a'H), RIM_APPLICATION_IDENTITY ('4b'H), RIM_SEQUENCE_NUMBER ('4c'H), RAN_INFO_REUEST_AC ('4d'H), RAN_INFO_AC ('4e'H), RIM_PDU_INDICATIONS ('4f'H), PFC_FLOC_CONTROL_PARAMETERS ('52'H), GLOBAL_CN_ID ('53'H), RIM_ROUTING_INFORMATION ('54'H), RIM_PROTOCOL_VERSION_NUMBER ('55'H), APP_ERROR_CONTAINER ('56'H), /* FIXME */ EXTENDED_FEATURE_BITMAP ('69'H) } with { variant "FIELDLENGTH(8)" }; 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)" }; /* 11.3.28 */ type record BssgpQosProfile { uint16_t r, BIT2 spare, boolean c_r, boolean t, boolean a, uint3_t precedence } with { variant (c_r) "FIELDLENGTH(1)" variant (t) "FIELDLENGTH(1)" variant (a) "FIELDLENGTH(1)" }; /* 11.3.84 */ type record BssgpFeatureBitmap { boolean mbms, boolean enh_radio_status, boolean pfc_fc, boolean rim, boolean lcs, boolean inr, boolean cbl, boolean pfc } with { variant "" }; /* 11.3.47 */ type record BssgpServiceUtranCco { uint5_t spare, uint3_t value_part } with { variant "" }; /* 11.3.84 */ type record BssgpExtendedFeatureBitmap { BIT7 spare, BIT1 ps_handover } with { variant "" }; type uint16_t BssgpPduLifetime; /* TS 48.008 3.2.2.18 */ type record BssmapPriority { BIT1 spare, boolean pci, uint4_t level, boolean qa, boolean pvi } with { variant "" }; type BssmapPriority BssgpPriority; type uint32_t BssgpTlli; type uint16_t BssgpBvci; type record BssgpCellId { RoutingAreaIdentification ra_id, CellIdentity cell_id } with { variant "" }; type union BssgpIeUnion { uint16_t bmax_default_ms, /* 11.3.2 */ uint16_t bucket_leak_rate, /* 11.3.4 */ uint16_t bvc_bucket_size, /* 11.3.5 */ BssgpBvci bvci, /* 11.3.6 */ uint16_t bvc_measurement, /* 11.3.7 */ BssgpCause cause, /* 11.3.8 */ BssgpCellId cell_id, /* 11.3.9 */ DrxParameter drx_parameter, /* 10.3.11 */ MobileIdentityV imsi, /* 11.3.14 */ LocationAreaIdentification lai, /* 11.3.17 */ MobileIdentityV mobile_id, /* 11.3.20 */ BssgpPduLifetime pdu_lifetime, /* 11.3.25 */ BssgpPriority priority, /* 11.3.27 */ BssgpQosProfile qos_profile, /* 11.3.28 */ BssgpTlli tlli, /* 11.3.25 */ uint16_t r_default_ms, /* 11.3.32 */ GsmTmsi tmsi, /* 11.3.36 */ BssgpServiceUtranCco svc_utran_cco, /* 11.3.47 */ BssgpFeatureBitmap feature_bitmap, /* 11.3.40 */ BssgpExtendedFeatureBitmap ext_feature_bitmap, /* 11.3.84 */ octetstring other }; type record BssgpTLV { BssgpIEI iei, /* we cannot express a variable-length "length" field with extension octets in the TTCN-3 * syntax, so we simply assume a plain 16 bit length value here and have a 'pseudl-BSSGP' * translator in front which explands all variable-length "length" fields to 16bits */ uint16_t len, BssgpIeUnion u } with { variant (u) "CROSSTAG( bmax_default_ms, iei = BMAX_DEFAULT_MS; bucket_leak_rate, iei = BUCKET_LEAK_RATE; bvc_bucket_size, iei = BVC_BUCKET_SIZE; bvci, iei = BVCI; bvc_measurement, iei = BVC_MEASUREMENT; cause, iei = CAUSE; cell_id, iei = CELL_ID; drx_parameter, iei = DRX_PARAMETERS; imsi, iei = IMSI; lai, iei = LOCATION_AREA; priority, iei = PRIORITY; mobile_id, iei = MOBILE_IDENTITY; pdu_lifetime, iei = PDU_LIFETIME; qos_profile, iei = QOS_PROFILE; tlli, iei = TLLI; r_default_ms, iei = R_DEFAULT_MS; tmsi, iei = TMSI; svc_utran_cco, iei = SERVICE_UTRAN_CCO; feature_bitmap, iei = FEATURE_BITMAP; ext_feature_bitmap, iei = EXTENDED_FEATURE_BITMAP; other, OTHERWISE)" variant (len) "LENGTHTO(u)" }; external function enc_BssgpTLV(in BssgpTLV pdu) return octetstring with { extension "prototype(convert) encode(RAW)" }; external function dec_BssgpTLV(in octetstring stream) return BssgpTLV with { extension "prototype(convert) decode(RAW)" }; type record of BssgpTLV BssgpTLVs; /* 10.2.1 */ type record BssgpDlUnitdata { BssgpTlli tlli, BssgpQosProfile qos_profile, BssgpTLV pdu_lifetime, /* optional parts */ BssgpTLVs tlvs } with { variant "" }; /* 10.2.2 */ type record BssgpUlUnitdata { BssgpTlli tlli, BssgpQosProfile qos_profile, BssgpTLV cell_id, /* optional parts */ BssgpTLVs tlvs } with { variant "" }; type record BssgpNormalPdu { BssgpTLVs tlvs optional } with { variant "" }; type union BssgpPduUnion { BssgpDlUnitdata dl_unitdata, BssgpUlUnitdata ul_unitdata, BssgpNormalPdu other }; type record BssgpPdu { BssgpPduType pdu_type, BssgpPduUnion u } with { variant (u) "CROSSTAG( dl_unitdata, pdu_type = DL_UNITDATA; ul_unitdata, pdu_type = UL_UNITDATA; other, OTHERWISE)" } external function enc_BssgpPdu(in BssgpPdu pdu) return octetstring with { extension "prototype(convert) encode(RAW)" }; external function dec_BssgpPdu(in octetstring stream) return BssgpPdu with { extension "prototype(convert) decode(RAW)" }; template BssgpPdu t_BSSGP_other(template BssgpPduType pdu_type, template BssgpTLVs tlvs) := { pdu_type := pdu_type, u := { other := { tlvs := tlvs } } } template BssgpTLV t_BSSGP_IE_Cause(template BssgpCause cause) := { iei := CAUSE, len := 1, u := { cause := cause } } template BssgpTLV t_BSSGP_IE_Bvci(template BssgpBvci bvci) := { iei := BVCI, len := 2, u := { bvci := bvci } } template BssgpTLV t_BSSGP_IE_CellId(template BssgpCellId cid) := { iei := CELL_ID, len := 8, u := { cell_id := cid } } template BssgpTLV t_BSSGP_IE_Lifetime(uint16_t time) := { iei := PDU_LIFETIME, len := 2, u := { pdu_lifetime := time } } template BssgpTLV t_BSSGP_IE_Tmsi(template GsmTmsi tmsi) := { iei := TMSI, len := 4, u := { tmsi := tmsi } } template BssgpTLV t_BSSGP_IE_Imsi(template hexstring imsi) := { iei := IMSI, len := 4, u := { mobile_id := tr_MI_IMSI(imsi) } } template BssgpTLV t_BSSGP_IE_Qos(BssgpQosProfile qos) := { iei := QOS_PROFILE, len := 0, u := { qos_profile := qos } } template BssgpTLV t_BssgpIE(template BssgpIEI iei, template BssgpIeUnion u) := { iei := iei, len := 0, u := u } template BssgpTLV t_BSSGP_IE_PDU(BssgpPdu pdu) := t_BssgpIE(PDU_IN_ERROR, { other := f_BSSGP_compact_len(enc_BssgpPdu(pdu)) }); template BssgpPdu t_BVC_RESET(template BssgpCause cause, template BssgpBvci bvci, template BssgpCellId cell_id) := t_BSSGP_other(BVC_RESET, { t_BSSGP_IE_Bvci(bvci), t_BSSGP_IE_Cause(cause), t_BSSGP_IE_CellId(cell_id) }); template BssgpPdu t_BVC_RESET_ACK(template BssgpBvci bvci, template BssgpCellId cell_id) := t_BSSGP_other(BVC_RESET_ACK, { t_BSSGP_IE_Bvci(bvci), t_BSSGP_IE_CellId(cell_id) }); template BssgpPdu t_BVC_UNBLOCK(template BssgpBvci bvci) := t_BSSGP_other(BVC_UNBLOCK, { t_BSSGP_IE_Bvci(bvci) }); template BssgpPdu t_BVC_UNBLOCK_ACK(template BssgpBvci bvci) := t_BSSGP_other(BVC_UNBLOCK_ACK, { t_BSSGP_IE_Bvci(bvci) }); template BssgpPdu t_BVC_BLOCK(template BssgpBvci bvci, template BssgpCause cause) := t_BSSGP_other(BVC_BLOCK, { t_BSSGP_IE_Bvci(bvci), t_BSSGP_IE_Cause(cause) }); template BssgpPdu t_BVC_BLOCK_ACK(template BssgpBvci bvci) := t_BSSGP_other(BVC_BLOCK_ACK, { t_BSSGP_IE_Bvci(bvci) }); template BssgpPdu tr_BSSGP_type(template BssgpPduType pdu_type, template BssgpPduUnion u := ?) := { pdu_type := pdu_type, u := u } template BssgpPdu t_BVC_FC_BVC := t_BSSGP_other(FLOW_CONTROL_BVC, ?); template BssgpPdu t_BVC_FC_BVC_ACK := t_BSSGP_other(FLOW_CONTROL_BVC_ACK, {}); template BssgpPdu t_BVC_FC_MS := t_BSSGP_other(FLOW_CONTROL_MS, ?); template BssgpPdu t_BVC_FC_MS_ACK := t_BSSGP_other(FLOW_CONTROL_MS_ACK, {}); template BssgpPdu t_BSSGP_STATUS(template BssgpTLVs tlvs) := t_BSSGP_other(STATUS, tlvs); } with { encode "RAW" };