osmo-ttcn3-hacks/library/GSM_Types.ttcn

588 lines
16 KiB
Plaintext

/* Encoding/Decoding routines for GSM System Information messages
* according to 3GPP TS 44.018 Version 12.3.0 Release 12 */
/* (C) 2017 by Harald Welte <laforge@gnumonks.org> */
module GSM_Types {
import from General_Types all;
import from Osmocom_Types all;
type integer GsmArfcn (0..1023);
type integer UmtsArfcn (0..16383);
type integer UmtsScramblingCode (0..511);
const integer GsmMaxFrameNumber := 26*51*2048;
type integer GsmFrameNumber (0..GsmMaxFrameNumber);
type integer GsmRxLev (0..63);
type integer GsmTsc (0..7) with { variant "FIELDLENGTH(8)" };
type uint32_t GsmTmsi;
/* Table 10.4.1 of Section 10.4 / 3GPP TS 44.018 */
type enumerated RrMessageType {
ADDITIONAL_ASSIGNMENT ('00111011'B),
IMMEDIATE_ASSIGNMENT ('00111111'B),
IMMEDIATE_ASSIGNMENT_EXTENDED ('00111001'B),
IMMEDIATE_ASSIGNMENT_REJECT ('00111010'B),
IMMEDIATE_PACKET_ASSIGNMENT ('01101001'B),
CIPHERING_MODE_COMMAND ('00110101'B),
CIPHERING_MODE_COMPLETE ('00110010'B),
CONFIGURATION_CHANGE_COMMAND ('00110000'B),
CONFIGURATION_CHANGE_ACK ('00110001'B),
CONFIGURATION_CHANGE_REJECT ('00110011'B),
ASSIGNMENT_COMMAND ('00101110'B),
ASSIGNMENT_COMPLETE ('00101001'B),
ASSIGNMENT_FAILURE ('00101111'B),
HANDOVER_COMMAND ('00101011'B),
HANDOVER_COMPLETE ('00101100'B),
HANDOVER_FAILURE ('00101000'B),
PHYSICAL_INFORMATION ('00101101'B),
CHANNEL_RELEASE ('00001101'B),
PARTIAL_RELEASE ('00001010'B),
PARTIAL_RELEASE_COMPLETE ('00001111'B),
PAGING_REQUEST_TYPE_1 ('00100001'B),
PAGING_REQUEST_TYPE_2 ('00100010'B),
PAGING_REQUEST_TYPE_3 ('00100100'B),
PAGING_RESPONSE ('00100111'B),
NOTIFICATION_NCH ('00100000'B),
NOTIFICATION_RESPOSNE ('00100110'B),
SYSTEM_INFORMATION_TYPE_8 ('00011000'B),
SYSTEM_INFORMATION_TYPE_1 ('00011001'B),
SYSTEM_INFORMATION_TYPE_2 ('00011010'B),
SYSTEM_INFORMATION_TYPE_3 ('00011011'B),
SYSTEM_INFORMATION_TYPE_4 ('00011100'B),
SYSTEM_INFORMATION_TYPE_5 ('00011101'B),
SYSTEM_INFORMATION_TYPE_6 ('00011110'B),
SYSTEM_INFORMATION_TYPE_7 ('00011111'B),
SYSTEM_INFORMATION_TYPE_2bis ('00000010'B),
SYSTEM_INFORMATION_TYPE_2ter ('00000011'B),
SYSTEM_INFORMATION_TYPE_2quater ('00000111'B),
SYSTEM_INFORMATION_TYPE_5bis ('00000101'B),
SYSTEM_INFORMATION_TYPE_5ter ('00000110'B),
SYSTEM_INFORMATION_TYPE_9 ('00000100'B),
SYSTEM_INFORMATION_TYPE_13 ('00000000'B),
SYSTEM_INFORMATION_TYPE_16 ('00111101'B),
SYSTEM_INFORMATION_TYPE_17 ('00111110'B),
CHANNEL_MODE_MODIFY ('00010000'B),
RR_STATUS ('00010010'B),
CHANNEL_MODE_MODIFY_ACKNOWLEDGE ('00010111'B),
FREQUENCY_REDEFINITION ('00010100'B),
MEASUREMENT_REPORT ('00010101'B),
CLASSMARK_CHANGE ('00010110'B),
CLASSMARK_ENQUIRY ('00010011'B),
EXTENDED_MEASUREMENT_REPORT ('00110110'B),
EXTENDED_MEASUREMENT_ORDER ('00110111'B),
GPRS_SUSPENSION_REQUEST ('00110100'B),
//MBMS_ANNOUNCEMENT ('00010110'B), duplicate?
//SERVICE_INFORMATION ('00110110'B), duplicate?
APPLICATION_INFORMATION ('00111000'B),
SYSTEM_INFORMATION_TYPE_14 ('00000001'B),
SYSTEM_INFORMATION_TYPE_15 ('01000011'B),
SYSTEM_INFORMATION_TYPE_18 ('01000000'B),
SYSTEM_INFORMATION_TYPE_19 ('01000001'B),
SYSTEM_INFORMATION_TYPE_20 ('01000010'B),
SYSTEM_INFORMATION_TYPE_13alt ('01000100'B),
SYSTEM_INFORMATION_TYPE_2n ('01000101'B),
SYSTEM_INFORMATION_TYPE_21 ('01000110'B),
SYSTEM_INFORMATION_TYPE_22 ('01000111'B),
SYSTEM_INFORMATION_TYPE_23 ('01001111'B),
DTM_ASSIGNMENT_FAILURE ('01001000'B),
DTM_REJECT ('01001001'B),
DTM_REQUEST ('01001010'B),
PACKET_ASSIGNMENT ('01001011'B),
DTM_ASSIGNMENT_COMMAND ('01001100'B),
DTM_INFORMATION ('01001101'B),
PACKET_INFORMATION ('01001110'B),
UTRAN_CLASSMARK_CHANGE ('01100000'B),
CDMA2000_CLASSMARK_CHANGE ('01100010'B),
INTERSYS_TO_UTRAN_HO_CMD ('01100011'B),
INTERSYS_TO_CDMA2000_HO_CMD ('01100100'B),
GERAN_IU_MODE_CLASSMARK_CHG ('01100101'B),
INTERSYS_TO_EUTRAN_HO_CMD ('01100110'B)
} with { variant "FIELDLENGTH(8)" };
type octetstring RestOctets with { variant "PADDING(yes), PADDING_PATTERN('00101011'B)" };
type hexstring GsmBcdString with { variant "HEXORDER(low)" };
type GsmBcdString BcdMccMnc with { variant "FIELDLENGTH(6)" };
type record L2PseudoLength {
uint6_t l2_plen,
BIT2 zero_one
} with { variant "" };
template L2PseudoLength t_L2Pseudolength(template uint6_t len) := {
l2_plen := len,
zero_one := '01'B
};
type record RrHeader {
L2PseudoLength l2_plen,
uint4_t skip_indicator,
uint4_t rr_protocol_discriminator,
RrMessageType message_type
} with { variant "" };
template RrHeader t_RrHeader(RrMessageType msg_type, template uint6_t len) := {
l2_plen := t_L2Pseudolength(len),
skip_indicator := 0,
rr_protocol_discriminator := 6,
message_type := msg_type
};
type record RrL3Header {
uint4_t skip_indicator,
uint4_t rr_protocol_discriminator,
RrMessageType message_type
} with { variant "" };
type record MaioHsn {
} with { variant "" };
/* TS 24.008 10.5.1.2 */
type uint4_t CipheringKeySeqNr (0..7);
/* 24.008 10.5.1.3 */
type record LocationAreaIdentification {
BcdMccMnc mcc_mnc,
uint16_t lac
} with { variant "" };
/* TS 24.008 10.5.1.4 */
type enumerated MobileIdentityType {
MI_TYPE_NONE (0),
MI_TYPE_IMSI,
MI_TYPE_IMEI,
MI_TYPE_IMEISV,
MI_TYPE_TMSI,
MI_TYPE_TMGI
} with { variant "FIELDLENGTH(3)" };
type record MobileIdentityBCD {
MobileIdentityType mi_type (MI_TYPE_IMSI, MI_TYPE_IMEI, MI_TYPE_IMEISV),
boolean odd,
hexstring digits
} with { variant "" };
type record MobileIdentityTMSI {
BIT4 pad ('1111'B),
boolean odd (false),
MobileIdentityType mi_type (MI_TYPE_TMSI),
GsmTmsi tmsi
} with { variant "" };
type record MobileIdentityNone {
BIT4 pad ('1111'B),
boolean odd (false),
MobileIdentityType mi_type (MI_TYPE_NONE)
} with { variant "" };
type union MobileIdentity {
MobileIdentityBCD bcd,
MobileIdentityTMSI tmsi,
MobileIdentityNone unused
} with { variant "TAG(bcd, mi_type = MI_TYPE_IMSI;
bcd, mi_type = MI_TYPE_IMEI;
bcd, mi_type = MI_TYPE_IMEISV;
tmsi, mi_type = MI_TYPE_TMSI;
unused, mi_type = MI_TYPE_NONE)" };
type record MobileIdentityLV {
uint8_t len,
MobileIdentity mi
} with { variant (len) "LENGTHTO(mi)" };
type record MobileIdentityTLV {
uint8_t tag,
uint8_t len,
MobileIdentity mi
} with { variant (len) "LENGTHTO(mi)" };
/* TS 24.008 10.5.1.5 */
type record MsClassmark1 {
BIT1 spare,
uint2_t rev_level,
boolean es_ind,
boolean a51,
uint3_t rf_pwr_cap
} with { variant "" };
/* TS 24.008 10.5.1.6 */
type record MsClassmark2 {
BIT1 spare,
uint2_t rev_level,
boolean es_ind,
boolean a51,
uint3_t rf_pwr_cap,
BIT1 spare1,
boolean ps_cap,
uint2_t ss_screen_ind,
boolean sm_cap,
boolean vbs,
boolean vgcs,
boolean fc,
boolean cm3,
BIT1 spare2,
boolean lcsva_cap,
boolean ucs2,
boolean solsa,
boolean cmsp,
boolean a53,
boolean a52
} with { variant "" };
type record MsClassmark2LV {
uint8_t len,
MsClassmark2 cm2
} with { variant (len) "LENGTHTO(cm2)" };
/* 44.018 10.5.2.5 */
type record ChannelDescription {
RslChannelNr chan_nr,
uint3_t tsc,
boolean h,
uint12_t arfcn optional,
MaioHsn maio_hsn optional
} with { variant (arfcn) "PRESENCE(h = false)"
variant (maio_hsn) "PRESENCE(h = true)" };
type record ChannelDescriptionTV {
OCT1 iei,
ChannelDescription v
} with { variant "" };
/* 10.5.2.8 */
type enumerated ChannelNeeded {
CHAN_NEED_ANY (0),
CHAN_NEED_SDCCH (1),
CHAN_NEED_TCH_F (2),
CHAN_NEED_TCH_H (3)
} with { variant "FIELDLENGTH(2)" };
type record ChannelNeeded12 {
ChannelNeeded second,
ChannelNeeded first
} with { variant "" };
/* 10.5.2.21 */
type record MobileAllocation {
uint8_t len,
bitstring ma
} with { variant (len) "LENGTHTO(ma)" };
/* 10.5.2.25a */
type OCT3 PacketChannelDescription;
/* 10.5.2.25b */
type record DedicatedModeOrTbf {
BIT1 spare,
boolean tma,
boolean downlink,
boolean tbf
} with { variant "" };
/* 10.5.2.26 */
type enumerated PageMode {
PAGE_MODE_NORMAL,
PAGE_MODE_EXTENDED,
PAGE_MODE_REORGANIZATION,
PAGE_MODE_SAME_AS_BEFORE
} with { variant "FIELDLENGTH(4)" };
/* 10.5.2.30 */
type record RequestReference {
bitstring ra length(8),
uint5_t t1p,
uint6_t t3,
uint5_t t2
} with { variant "" };
template RequestReference t_RequestReference(template bitstring ra, template uint5_t t1p, template uint6_t t3, template uint5_t t2) := {
ra := ra,
t1p := t1p,
t3 := t3,
t2 := t2
}
/* compute the expected request reference for given RA + FN */
function f_compute_ReqRef(uint8_t ra, GsmFrameNumber fn) return RequestReference {
var RequestReference req_ref := { ra := int2bit(ra, 8) };
req_ref.t1p := (fn / 1326) mod 32;
req_ref.t2 := fn mod 26;
req_ref.t3 := fn mod 51;
return req_ref
}
/* 10.5.2.40 */
type integer TimingAdvance (0..219);
/* 10.5.2.43 */
type uint8_t WaitIndication;
/* 10.5.2.76 */
type record FeatureIndicator {
BIT2 spare,
boolean cs_ir,
boolean ps_ir
} with { variant "" };
/* 9.1.18 */
type record ImmediateAssignment {
DedicatedModeOrTbf ded_or_tbf,
PageMode page_mode,
ChannelDescription chan_desc optional,
PacketChannelDescription pkt_chan_desc optional,
RequestReference req_ref,
TimingAdvance timing_advance,
MobileAllocation mobile_allocation
} with { variant (chan_desc) "PRESENCE(ded_or_tbf.tbf = false)"
variant (pkt_chan_desc) "PRESENCE(ded_or_tbf.tbf = true)" };
/* 9.1.20 */
type record ReqRefWaitInd {
RequestReference req_ref,
WaitIndication wait_ind
} with { variant "" };
type record length(4) of ReqRefWaitInd ReqRefWaitInd4;
type record ImmediateAssignmentReject {
FeatureIndicator feature_ind,
PageMode page_mode,
ReqRefWaitInd4 payload
} with { variant "" };
/* 9.1.22 */
type record PagingRequestType1 {
ChannelNeeded12 chan_needed,
PageMode page_mode,
MobileIdentityLV mi1,
MobileIdentityTLV mi2 optional,
RestOctets rest_octets
} with { variant "TAG(mi2, tag = 23)" };
/* 9.1.23 */
type record PagingRequestType2 {
ChannelNeeded12 chan_needed,
PageMode page_mode,
GsmTmsi mi1,
GsmTmsi mi2,
MobileIdentityTLV mi3 optional,
RestOctets rest_octets
} with { variant "TAG(mi3, tag = 23)" };
/* 9.1.24 */
type record length(4) of GsmTmsi GsmTmsi4;
type record PagingRequestType3 {
ChannelNeeded12 chan_needed,
PageMode page_mode,
GsmTmsi4 mi,
RestOctets rest_octets
} with { variant "" };
type union RrUnion {
/*
SystemInformationType1 si1,
SystemInformationType2 si2,
SystemInformationType2bis si2bis,
SystemInformationType2ter si2ter,
SystemInformationType3 si3,
SystemInformationType4 si4,
SystemInformationType5 si5,
SystemInformationType5bis si5bis,
SystemInformationType5ter si5ter,
SystemInformationType6 si6,
*/
ImmediateAssignment imm_ass,
ImmediateAssignmentReject imm_ass_rej,
PagingRequestType1 pag_req_1,
PagingRequestType2 pag_req_2,
PagingRequestType3 pag_req_3,
octetstring other
} with { variant "" };
/* Special RR Message on BCCH / CCCH Dowlink */
type record GsmRrMessage {
RrHeader header,
RrUnion payload
} with { variant (payload) "CROSSTAG(
/*
si1, header.message_type = SYSTEM_INFORMATION_TYPE_1;
si2, header.message_type = SYSTEM_INFORMATION_TYPE_2;
si2bis, header.message_type = SYSTEM_INFORMATION_TYPE_2bis;
si2ter, header.message_type = SYSTEM_INFORMATION_TYPE_2ter;
si3, header.message_type = SYSTEM_INFORMATION_TYPE_3;
si4, header.message_type = SYSTEM_INFORMATION_TYPE_4;
si5, header.message_type = SYSTEM_INFORMATION_TYPE_5;
si5bis, header.message_type = SYSTEM_INFORMATION_TYPE_5bis;
si5ter, header.message_type = SYSTEM_INFORMATION_TYPE_5ter;
si6, header.message_type = SYSTEM_INFORMATION_TYPE_6;
*/
imm_ass, header.message_type = IMMEDIATE_ASSIGNMENT;
imm_ass_rej, header.message_type = IMMEDIATE_ASSIGNMENT_REJECT;
pag_req_1, header.message_type = PAGING_REQUEST_TYPE_1;
pag_req_2, header.message_type = PAGING_REQUEST_TYPE_2;
pag_req_3, header.message_type = PAGING_REQUEST_TYPE_3;
other, OTHERWISE;
)" };
external function enc_GsmRrMessage(in GsmRrMessage msg) return octetstring
with { extension "prototype(convert) encode(RAW)" };
external function dec_GsmRrMessage(in octetstring stream) return GsmRrMessage
with { extension "prototype(convert) decode(RAW)" };
/* Normal L3 Message on Dedicated Channel */
/* 9.1.25 Paging Response */
type record PagingResponse {
uint4_t spare_half_octet,
CipheringKeySeqNr cksn,
MsClassmark2LV cm2,
MobileIdentityLV mi,
uint8_t addl_upd_par optional
} with { variant "" };
type union RrL3Union {
PagingResponse paging_response,
octetstring other
};
type record GsmRrL3Message {
RrL3Header header,
RrL3Union payload
} with { variant (payload) "CROSSTAG(
paging_response, header.message_type = PAGING_RESPONSE;
other, OTHERWISE;
)" }
/* TS 48.058 9.3.1 Channel Number IE */
type enumerated RslChanNr0 {
RSL_CHAN_NR_INVALID ('00'H),
RSL_CHAN_NR_Bm_ACCH ('01'H),
RSL_CHAN_NR_BCCH ('10'H),
RSL_CHAN_NR_RACH ('11'H),
RSL_CHAN_NR_PCH_AGCH ('12'H)
} with { variant "FIELDLENGTH(5)" };
type record RslChanNr2 {
BIT4 tag ('0001'B),
uint1_t sub_chan
} with { variant "FIELDLENGTH(5)" };
type record RslChanNr4 {
BIT3 tag ('001'B),
uint2_t sub_chan
} with { variant "FIELDLENGTH(5)" };
type record RslChanNr8 {
BIT2 tag ('01'B),
uint3_t sub_chan
} with { variant "FIELDLENGTH(5)" };
type union RslChanNrU {
RslChanNr0 ch0,
RslChanNr2 lm,
RslChanNr4 sdcch4,
RslChanNr8 sdcch8
} with {
variant "TAG(lm, tag = '0001'B;
sdcch4, tag = '001'B;
sdcch8, tag = '01'B;
ch0, OTHERWISE)"
variant "FIELDLENGTH(5)"
};
type record RslChannelNr {
RslChanNrU u,
uint3_t tn
} with { variant "FIELDLENGTH(8)" };
template RslChannelNr t_RslChanNr0(template uint3_t tn, template RslChanNr0 cht) := {
u := { ch0 := cht },
tn := tn
}
template RslChannelNr t_RslChanNr_RACH(template uint3_t tn) := t_RslChanNr0(tn, RSL_CHAN_NR_RACH);
template RslChannelNr t_RslChanNr_BCCH(template uint3_t tn) := t_RslChanNr0(tn, RSL_CHAN_NR_BCCH);
template RslChannelNr t_RslChanNr_PCH_AGCH(template uint3_t tn) := t_RslChanNr0(tn, RSL_CHAN_NR_PCH_AGCH);
template RslChannelNr t_RslChanNr_Bm(template uint3_t tn) := t_RslChanNr0(tn, RSL_CHAN_NR_Bm_ACCH);
template RslChannelNr t_RslChanNr_Lm(template uint3_t tn, uint1_t sub_slot) := {
u := { lm := { tag := '0001'B, sub_chan := sub_slot } },
tn := tn
}
template RslChannelNr t_RslChanNr_SDCCH4(template uint3_t tn, template uint2_t sub_slot) := {
u := { sdcch4 := { tag := '001'B, sub_chan := sub_slot } },
tn := tn
}
template RslChannelNr t_RslChanNr_SDCCH8(template uint3_t tn, template uint3_t sub_slot) := {
u := { sdcch8 := { tag := '01'B, sub_chan := sub_slot } },
tn := tn
}
/* TS 48.058 9.3.2 Link ID */
type enumerated RslLinkIdC {
FACCH_SDCCH (0),
SACCH (1)
} with { variant "FIELDLENGTH(2)" };
type enumerated RslSapi0Prio {
SAPI0_PRIO_NORMAL (0),
SAPI0_PRIO_HIGH (1),
SAPI0_PRIO_LOW (2)
} with { variant "FIELDLENGTH(2)" };
type uint3_t GsmSapi;
type record RslLinkId {
RslLinkIdC c,
boolean na,
RslSapi0Prio prio,
GsmSapi sapi
} with { variant "" };
template RslLinkId tr_RslLinkId := {
c := ?,
na := ?,
prio := ?,
sapi := ?
};
template RslLinkId tr_RslLinkID_DCCH(template GsmSapi sapi) modifies tr_RslLinkId := {
c := FACCH_SDCCH,
na := false,
sapi := sapi
};
template RslLinkId tr_RslLinkID_SACCH(template GsmSapi sapi) modifies tr_RslLinkId := {
c := SACCH,
na := false,
sapi := sapi
};
template RslLinkId ts_RslLinkID_DCCH(GsmSapi sapi) := {
c := FACCH_SDCCH,
na := false,
prio := SAPI0_PRIO_NORMAL,
sapi := sapi
};
template RslLinkId ts_RslLinkID_SACCH(GsmSapi sapi) := {
c := SACCH,
na := false,
prio := SAPI0_PRIO_NORMAL,
sapi := sapi
};
} with { encode "RAW"; variant "FIELDORDER(msb)" }