788 lines
19 KiB
Plaintext
788 lines
19 KiB
Plaintext
/* Data Types / Encoding / Decoding for OsmocomBB L1CTL interface */
|
|
/* (C) 2017 by Harald Welte <laforge@gnumonks.org>, derived from l1ctl_proto.h
|
|
* which is (C) 2010 by Harald Welte + Holger Hans Peter Freyther
|
|
* 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 L1CTL_Types {
|
|
|
|
import from General_Types all;
|
|
import from GSM_Types all;
|
|
import from GSM_RR_Types all;
|
|
import from Osmocom_Types all;
|
|
|
|
type uint32_t uint32_le with { variant "BYTEORDER(first)" };
|
|
|
|
type enumerated L1ctlMsgType {
|
|
L1CTL_NONE,
|
|
L1CTL_FBSB_REQ,
|
|
L1CTL_FBSB_CONF,
|
|
L1CTL_DATA_IND,
|
|
L1CTL_RACH_REQ,
|
|
L1CTL_DM_EST_REQ,
|
|
L1CTL_DATA_REQ,
|
|
L1CTL_RESET_IND,
|
|
L1CTL_PM_REQ, /* power measurement */
|
|
L1CTL_PM_CONF, /* power measurement */
|
|
L1CTL_ECHO_REQ,
|
|
L1CTL_ECHO_CONF,
|
|
L1CTL_RACH_CONF,
|
|
L1CTL_RESET_REQ,
|
|
L1CTL_RESET_CONF,
|
|
L1CTL_DATA_CONF,
|
|
L1CTL_CCCH_MODE_REQ,
|
|
L1CTL_CCCH_MODE_CONF,
|
|
L1CTL_DM_REL_REQ,
|
|
L1CTL_PARAM_REQ,
|
|
L1CTL_DM_FREQ_REQ,
|
|
L1CTL_CRYPTO_REQ,
|
|
L1CTL_SIM_REQ,
|
|
L1CTL_SIM_CONF,
|
|
L1CTL_TCH_MODE_REQ,
|
|
L1CTL_TCH_MODE_CONF,
|
|
L1CTL_NEIGH_PM_REQ,
|
|
L1CTL_NEIGH_PM_IND,
|
|
L1CTL_TRAFFIC_REQ,
|
|
L1CTL_TRAFFIC_CONF,
|
|
L1CTL_TRAFFIC_IND,
|
|
L1CTL_BURST_IND,
|
|
L1CTL_TBF_CFG_REQ,
|
|
L1CTL_TBF_CFG_CONF,
|
|
L1CTL_DATA_TBF_REQ,
|
|
L1CTL_DATA_TBF_CONF,
|
|
L1CTL_EXT_RACH_REQ,
|
|
L1CTL_DATA_ABS_REQ /*!< FIXME: no such message in OsmocomBB */
|
|
} with { variant "FIELDLENGTH(8)" };
|
|
|
|
type enumerated L1ctlCcchMode {
|
|
CCCH_MODE_NONE (0),
|
|
CCCH_MODE_NON_COMBINED,
|
|
CCCH_MODE_COMBINED,
|
|
CCCH_MODE_COMBINED_CBCH
|
|
} with { variant "FIELDLENGTH(8)" };
|
|
|
|
type enumerated L1ctlNeighMode {
|
|
NEIGH_MODE_NONE (0),
|
|
NEIGH_MODE_PM,
|
|
NEIGH_MODE_SB
|
|
} with { variant "FIELDLENGTH(8)" };
|
|
|
|
type enumerated L1ctlGprsCs {
|
|
L1CTL_CS1 (1),
|
|
L1CTL_CS2,
|
|
L1CTL_CS3,
|
|
L1CTL_CS4,
|
|
L1CTL_MCS1,
|
|
L1CTL_MCS2,
|
|
L1CTL_MCS3,
|
|
L1CTL_MCS4,
|
|
L1CTL_MCS5,
|
|
L1CTL_MCS6,
|
|
L1CTL_MCS7,
|
|
L1CTL_MCS8,
|
|
L1CTL_MCS9
|
|
} with { variant "FIELDLENGTH(8)" };
|
|
|
|
type enumerated L1ctlResetType {
|
|
L1CTL_RES_T_BOOT (0),
|
|
L1CTL_RES_T_FULL,
|
|
L1CTL_RES_T_SCHED
|
|
} with { variant "FIELDLENGTH(8)" };
|
|
|
|
type record L1ctlHdrFlags {
|
|
BIT7 padding,
|
|
boolean f_done
|
|
} with { variant "" };
|
|
|
|
type record L1ctlHeader {
|
|
L1ctlMsgType msg_type,
|
|
L1ctlHdrFlags flags,
|
|
OCT2 padding
|
|
} with { variant "" };
|
|
|
|
template L1ctlHeader tr_L1ctlHeader(template L1ctlMsgType msg_type) := {
|
|
msg_type := msg_type,
|
|
flags := ?,
|
|
padding := ?
|
|
};
|
|
|
|
template (value) L1ctlHeader ts_L1ctlHeader(L1ctlMsgType msg_type) := {
|
|
msg_type := msg_type,
|
|
flags := { padding := '0000000'B, f_done := false },
|
|
padding := '0000'O
|
|
};
|
|
|
|
type record L1ctlDlInfo {
|
|
RslChannelNr chan_nr,
|
|
RslLinkId link_id,
|
|
Arfcn arfcn,
|
|
uint32_t frame_nr,
|
|
GsmRxLev rx_level,
|
|
uint8_t snr,
|
|
uint8_t num_biterr,
|
|
uint8_t fire_crc
|
|
} with { variant "" };
|
|
|
|
type record L1ctlFbsbConf {
|
|
int16_t initial_freq_err,
|
|
uint8_t result,
|
|
uint8_t bsic
|
|
} with { variant "" };
|
|
|
|
type record L1ctlCcchModeConf {
|
|
L1ctlCcchMode ccch_mode,
|
|
OCT3 padding
|
|
} with { variant "" };
|
|
|
|
/* gsm48_chan_mode */
|
|
type uint8_t L1ctlTchMode;
|
|
|
|
type record L1ctlAudioMode {
|
|
BIT4 padding,
|
|
boolean tx_microphone,
|
|
boolean tx_traffic_req,
|
|
boolean rx_speaker,
|
|
boolean rx_traffic_ind
|
|
} with { variant "" };
|
|
|
|
template (value) L1ctlAudioMode t_L1CTL_AudioModeNone := { '0000'B, false, false, false, false };
|
|
|
|
type record L1ctlTchModeConf {
|
|
L1ctlTchMode tch_mode,
|
|
L1ctlAudioMode audio_mode,
|
|
OCT2 padding
|
|
} with { variant "" };
|
|
|
|
type record L1ctlDataInd {
|
|
octetstring payload
|
|
} with {
|
|
variant (payload) "BYTEORDER(first)"
|
|
};
|
|
|
|
type union L1ctlDlPayload {
|
|
L1ctlFbsbConf fbsb_conf,
|
|
L1ctlCcchModeConf ccch_mode_conf,
|
|
L1ctlTchModeConf tch_mode_conf,
|
|
L1ctlDataInd data_ind,
|
|
L1ctlTrafficReq traffic_ind,
|
|
L1ctlTbfCfgReq tbf_cfg_conf,
|
|
octetstring other
|
|
} with {
|
|
variant (other) "BYTEORDER(first)"
|
|
};
|
|
|
|
type record L1ctlDlMessage {
|
|
L1ctlHeader header,
|
|
L1ctlDlInfo dl_info optional,
|
|
L1ctlDlPayload payload optional
|
|
} with { variant (dl_info) "PRESENCE(header.msg_type = L1CTL_FBSB_CONF,
|
|
header.msg_type = L1CTL_RACH_CONF,
|
|
header.msg_type = L1CTL_DATA_IND,
|
|
header.msg_type = L1CTL_DATA_CONF,
|
|
header.msg_type = L1CTL_TRAFFIC_IND,
|
|
header.msg_type = L1CTL_TRAFFIC_CONF)"
|
|
variant (payload) "CROSSTAG(fbsb_conf, header.msg_type = L1CTL_FBSB_CONF;
|
|
ccch_mode_conf, header.msg_type = L1CTL_CCCH_MODE_CONF;
|
|
tch_mode_conf, header.msg_type = L1CTL_TCH_MODE_CONF;
|
|
data_ind, header.msg_type = L1CTL_DATA_IND;
|
|
traffic_ind, header.msg_type = L1CTL_TRAFFIC_IND;
|
|
tbf_cfg_conf, header.msg_type = L1CTL_TBF_CFG_CONF;
|
|
other, OTHERWISE;
|
|
)" };
|
|
|
|
external function enc_L1ctlDlMessage(in L1ctlDlMessage msg) return octetstring
|
|
with { extension "prototype(convert) encode(RAW)" };
|
|
external function dec_L1ctlDlMessage(in octetstring stream) return L1ctlDlMessage
|
|
with { extension "prototype(convert) decode(RAW)" };
|
|
|
|
|
|
type record L1ctlUlInfo {
|
|
RslChannelNr chan_nr,
|
|
RslLinkId link_id,
|
|
OCT2 padding
|
|
} with { variant "" };
|
|
|
|
type record L1ctlUlTbfInfo {
|
|
uint8_t tbf_nr,
|
|
L1ctlGprsCs cs,
|
|
OCT2 padding
|
|
} with { variant "" };
|
|
|
|
type record L1ctlUlAbsInfo {
|
|
uint8_t tbf_nr,
|
|
L1ctlGprsCs cs,
|
|
uint8_t ts_nr,
|
|
OCT1 padding,
|
|
uint32_le fn,
|
|
Arfcn arfcn,
|
|
OCT2 padding2
|
|
} with { variant "" };
|
|
|
|
type record L1ctlFbsbFlags {
|
|
BIT5 padding,
|
|
boolean sb,
|
|
boolean fb1,
|
|
boolean fb0
|
|
} with { variant "FIELDORDER(msb)" };
|
|
|
|
template (value) L1ctlFbsbFlags t_L1CTL_FBSB_F_ALL := {
|
|
padding := '00000'B,
|
|
sb := true,
|
|
fb1 := true,
|
|
fb0 := true
|
|
};
|
|
|
|
type record L1ctlFbsbReq {
|
|
Arfcn arfcn,
|
|
uint16_t timeout_tdma_frames,
|
|
uint16_t freq_err_thresh1,
|
|
uint16_t freq_err_thresh2,
|
|
uint8_t num_freqerr_avg,
|
|
L1ctlFbsbFlags flags,
|
|
uint8_t sync_info_idx,
|
|
L1ctlCcchMode ccch_mode,
|
|
GsmRxLev rxlev_exp
|
|
} with { variant "" };
|
|
|
|
type record L1ctlCcchModeReq {
|
|
L1ctlCcchMode ccch_mode,
|
|
OCT3 padding
|
|
} with { variant "" };
|
|
|
|
type record L1ctlTchModeReq {
|
|
L1ctlTchMode tch_mode,
|
|
L1ctlAudioMode audio_mode,
|
|
OCT2 padding
|
|
} with { variant "" };
|
|
|
|
type record L1ctlRachReq {
|
|
uint8_t ra,
|
|
uint8_t combined,
|
|
uint16_t offset
|
|
} with { variant "" };
|
|
|
|
type enumerated L1ctlRachSynchSeq {
|
|
RACH_SYNCH_SEQ_TS0 (0),
|
|
RACH_SYNCH_SEQ_TS1,
|
|
RACH_SYNCH_SEQ_TS2
|
|
} with { variant "FIELDLENGTH(8)" };
|
|
|
|
type record L1ctlExtRachReq {
|
|
uint16_t ra11,
|
|
L1ctlRachSynchSeq synch_seq,
|
|
uint8_t combined,
|
|
uint16_t offset
|
|
} with { variant "" };
|
|
|
|
type record L1ctlParReq {
|
|
int8_t ta,
|
|
uint8_t tx_power,
|
|
OCT2 padding
|
|
} with { variant "" };
|
|
|
|
type record L1ctlDataReq {
|
|
SacchL1Header l1header optional,
|
|
octetstring l2_payload
|
|
} with { variant "" };
|
|
|
|
type record L1ctlH1 {
|
|
uint8_t hsn,
|
|
uint8_t maio,
|
|
uint8_t n,
|
|
OCT1 padding,
|
|
bitstring ma length(64)
|
|
} with { variant "" };
|
|
|
|
type record L1ctlDmEstReq {
|
|
GsmTsc tsc,
|
|
uint8_t h,
|
|
Arfcn arfcn optional,
|
|
L1ctlH1 hopping optional,
|
|
L1ctlTchMode tch_mode,
|
|
L1ctlAudioMode audio_mode
|
|
} with { variant (arfcn) "PRESENCE(h = 0)"
|
|
variant (hopping) "PRESENCE(h = 1)" };
|
|
|
|
type record L1ctlReset {
|
|
L1ctlResetType reset_type,
|
|
OCT3 padding
|
|
} with { variant "" };
|
|
|
|
type record L1CtlCryptoReq {
|
|
uint8_t algo,
|
|
uint8_t key_len,
|
|
octetstring key
|
|
} with { variant (key_len) "LENGTHTO(key)" };
|
|
|
|
|
|
type record L1ctlTrafficReq {
|
|
octetstring data
|
|
} with {
|
|
variant (data) "BYTEORDER(first)"
|
|
}
|
|
|
|
type record length(8) of uint8_t TfiUsfArr;
|
|
|
|
type record L1ctlTbfCfgReq {
|
|
uint8_t tbf_nr,
|
|
boolean is_uplink,
|
|
OCT2 padding,
|
|
TfiUsfArr tfi_usf
|
|
} with { variant (is_uplink) "FIELDLENGTH(8)" };
|
|
|
|
type union L1ctlUlPayload {
|
|
L1ctlFbsbReq fbsb_req,
|
|
L1ctlCcchModeReq ccch_mode_req,
|
|
L1ctlTchModeReq tch_mode_req,
|
|
L1ctlRachReq rach_req,
|
|
L1ctlExtRachReq ext_rach_req,
|
|
L1ctlParReq par_req,
|
|
L1ctlDmEstReq dm_est_req,
|
|
L1ctlReset reset_req,
|
|
//L1ctlNeighPmReq neigh_pm_req,
|
|
L1CtlCryptoReq crypto_req,
|
|
L1ctlTrafficReq traffic_req,
|
|
L1ctlTbfCfgReq tbf_cfg_req,
|
|
L1ctlDataReq data_req,
|
|
octetstring other
|
|
} with {
|
|
variant (other) "BYTEORDER(first)"
|
|
};
|
|
|
|
type record L1ctlUlMessage {
|
|
L1ctlHeader header,
|
|
L1ctlUlInfo ul_info optional,
|
|
L1ctlUlTbfInfo ul_info_tbf optional,
|
|
L1ctlUlAbsInfo ul_info_abs optional,
|
|
L1ctlUlPayload payload
|
|
} with { variant (ul_info) "PRESENCE(header.msg_type = L1CTL_RACH_REQ,
|
|
header.msg_type = L1CTL_EXT_RACH_REQ,
|
|
header.msg_type = L1CTL_PARAM_REQ,
|
|
header.msg_type = L1CTL_CRYPTO_REQ,
|
|
header.msg_type = L1CTL_DATA_REQ,
|
|
header.msg_type = L1CTL_DM_EST_REQ,
|
|
header.msg_type = L1CTL_DM_FREQ_REQ,
|
|
header.msg_type = L1CTL_DM_REL_REQ,
|
|
header.msg_type = L1CTL_TRAFFIC_REQ)"
|
|
variant (ul_info_tbf) "PRESENCE(header.msg_type = L1CTL_DATA_TBF_REQ)"
|
|
variant (ul_info_abs) "PRESENCE(header.msg_type = L1CTL_DATA_ABS_REQ)"
|
|
variant (payload) "CROSSTAG(fbsb_req, header.msg_type = L1CTL_FBSB_REQ;
|
|
ccch_mode_req, header.msg_type = L1CTL_CCCH_MODE_REQ;
|
|
tch_mode_req, header.msg_type = L1CTL_TCH_MODE_REQ;
|
|
rach_req, header.msg_type = L1CTL_RACH_REQ;
|
|
ext_rach_req, header.msg_type = L1CTL_EXT_RACH_REQ;
|
|
par_req, header.msg_type = L1CTL_PARAM_REQ;
|
|
dm_est_req, header.msg_type = L1CTL_DM_EST_REQ;
|
|
reset_req, header.msg_type = L1CTL_RESET_REQ;
|
|
crypto_req, header.msg_type = L1CTL_CRYPTO_REQ;
|
|
traffic_req, header.msg_type = L1CTL_TRAFFIC_REQ;
|
|
tbf_cfg_req, header.msg_type = L1CTL_TBF_CFG_REQ;
|
|
data_req, header.msg_type = L1CTL_DATA_REQ;
|
|
other, OTHERWISE;
|
|
)" };
|
|
|
|
external function enc_L1ctlUlMessage(in L1ctlUlMessage msg) return octetstring
|
|
with { extension "prototype(convert) encode(RAW)" };
|
|
external function dec_L1ctlUlMessage(in octetstring stream) return L1ctlUlMessage
|
|
with { extension "prototype(convert) decode(RAW)" };
|
|
|
|
type record L1ctlUlMessageLV {
|
|
uint16_t len,
|
|
L1ctlUlMessage msg
|
|
} with { variant (len) "LENGTHTO(msg)" };
|
|
|
|
external function enc_L1ctlUlMessageLV(in L1ctlUlMessageLV msg) return octetstring
|
|
with { extension "prototype(convert) encode(RAW)" };
|
|
external function dec_L1ctlUlMessageLV(in octetstring stream) return L1ctlUlMessageLV
|
|
with { extension "prototype(convert) decode(RAW)" };
|
|
|
|
type record L1ctlDlMessageLV {
|
|
uint16_t len,
|
|
L1ctlDlMessage msg
|
|
} with { variant (len) "LENGTHTO(msg)" };
|
|
|
|
external function enc_L1ctlDlMessageLV(in L1ctlDlMessageLV msg) return octetstring
|
|
with { extension "prototype(convert) encode(RAW)" };
|
|
external function dec_L1ctlDlMessageLV(in octetstring stream) return L1ctlDlMessageLV
|
|
with { extension "prototype(convert) decode(RAW)" };
|
|
|
|
|
|
|
|
|
|
/* for generating RESET_REQ */
|
|
template (value) L1ctlUlMessage t_L1ctlResetReq(L1ctlResetType rst_type) := {
|
|
header := ts_L1ctlHeader(L1CTL_RESET_REQ),
|
|
ul_info := omit,
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
reset_req := {
|
|
reset_type := rst_type,
|
|
padding := '000000'O
|
|
}
|
|
}
|
|
};
|
|
|
|
/* for generating FBSB_REQ */
|
|
template (value) L1ctlUlMessage ts_L1CTL_FBSB_REQ(Arfcn arfcn, L1ctlFbsbFlags flags,
|
|
uint8_t sync_info_idx,
|
|
L1ctlCcchMode ccch_mode,
|
|
GsmRxLev rxlev_exp) := {
|
|
header := ts_L1ctlHeader(L1CTL_FBSB_REQ),
|
|
ul_info := omit,
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
fbsb_req := {
|
|
arfcn := arfcn,
|
|
timeout_tdma_frames := 250, /* about 1s */
|
|
freq_err_thresh1 := 10000,
|
|
freq_err_thresh2 := 800,
|
|
num_freqerr_avg := 3,
|
|
flags := flags,
|
|
sync_info_idx := sync_info_idx,
|
|
ccch_mode := ccch_mode,
|
|
rxlev_exp := rxlev_exp
|
|
}
|
|
}
|
|
};
|
|
|
|
/* for matching against incoming FBSB_CONF */
|
|
template L1ctlDlMessage tr_L1CTL_FBSB_CONF(template uint8_t result) := {
|
|
header := tr_L1ctlHeader(L1CTL_FBSB_CONF),
|
|
dl_info := ?,
|
|
payload := {
|
|
fbsb_conf := {
|
|
initial_freq_err := ?,
|
|
result := result,
|
|
bsic := ?
|
|
}
|
|
}
|
|
};
|
|
|
|
template (value) L1ctlUlMessage ts_L1CTL_CCCH_MODE_REQ(L1ctlCcchMode ccch_mode) := {
|
|
header := ts_L1ctlHeader(L1CTL_CCCH_MODE_REQ),
|
|
ul_info := omit,
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
ccch_mode_req := {
|
|
ccch_mode := ccch_mode,
|
|
padding := '000000'O
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
template L1ctlDlMessage tr_L1CTL_MsgType(template L1ctlMsgType msg_type) := {
|
|
header := tr_L1ctlHeader(msg_type),
|
|
dl_info := *,
|
|
payload := *
|
|
}
|
|
|
|
template L1ctlDlMessage tr_L1CTL_CCCH_MODE_CONF := tr_L1CTL_MsgType(L1CTL_CCCH_MODE_CONF);
|
|
|
|
template L1ctlUlMessage ts_L1CTL_RACH_REQ(uint8_t ra, uint8_t combined, uint16_t offset,
|
|
template (value) RslChannelNr chan_nr := ts_RslChanNr_RACH(0),
|
|
template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0)) := {
|
|
header := ts_L1ctlHeader(L1CTL_RACH_REQ),
|
|
ul_info := {
|
|
chan_nr := chan_nr,
|
|
link_id := link_id,
|
|
padding := '0000'O
|
|
},
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
rach_req := {
|
|
ra := ra,
|
|
combined := combined,
|
|
offset := offset
|
|
}
|
|
}
|
|
}
|
|
|
|
template L1ctlUlMessage ts_L1CTL_EXT_RACH_REQ(
|
|
uint16_t ra11, L1ctlRachSynchSeq seq,
|
|
uint8_t combined, uint16_t offset
|
|
) := {
|
|
header := ts_L1ctlHeader(L1CTL_EXT_RACH_REQ),
|
|
ul_info := {
|
|
/* FIXME: both RSL chan_nr and link_id should be configurable */
|
|
chan_nr := t_RslChanNr_RACH(0),
|
|
link_id := ts_RslLinkID_DCCH(0),
|
|
padding := '0000'O
|
|
},
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
ext_rach_req := {
|
|
ra11 := ra11,
|
|
synch_seq := seq,
|
|
combined := combined,
|
|
offset := offset
|
|
}
|
|
}
|
|
}
|
|
|
|
template L1ctlUlMessage ts_L1CTL_PAR_REQ(uint8_t ta, uint8_t tx_power) := {
|
|
header := ts_L1ctlHeader(L1CTL_PARAM_REQ),
|
|
ul_info := {
|
|
chan_nr := t_RslChanNr_RACH(0),
|
|
link_id := ts_RslLinkID_DCCH(0),
|
|
padding := '0000'O
|
|
},
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
par_req := {
|
|
ta := ta,
|
|
tx_power := tx_power,
|
|
padding := '0000'O
|
|
}
|
|
}
|
|
}
|
|
|
|
template L1ctlUlMessage ts_L1CTL_DM_EST_REQ(Arfcn arfcn, RslChannelNr chan_nr, GsmTsc tsc) := {
|
|
header := ts_L1ctlHeader(L1CTL_DM_EST_REQ),
|
|
ul_info := {
|
|
chan_nr := chan_nr,
|
|
link_id := ts_RslLinkID_DCCH(0),
|
|
padding := '0000'O
|
|
},
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
dm_est_req := {
|
|
tsc := tsc,
|
|
h := 0,
|
|
arfcn := arfcn,
|
|
hopping := omit,
|
|
tch_mode := 0,
|
|
audio_mode := t_L1CTL_AudioModeNone
|
|
}
|
|
}
|
|
}
|
|
|
|
template L1ctlUlMessage ts_L1CTL_DM_REL_REQ(RslChannelNr chan_nr) := {
|
|
header := ts_L1ctlHeader(L1CTL_DM_REL_REQ),
|
|
ul_info := {
|
|
chan_nr := chan_nr,
|
|
link_id := ts_RslLinkID_DCCH(0),
|
|
padding := '0000'O
|
|
},
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
other := ''O
|
|
}
|
|
}
|
|
|
|
template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ(template (value) RslChannelNr chan_nr,
|
|
template (value) RslLinkId link_id,
|
|
octetstring l2_data) := {
|
|
header := ts_L1ctlHeader(L1CTL_DATA_REQ),
|
|
ul_info := {
|
|
chan_nr := chan_nr,
|
|
link_id := link_id,
|
|
padding := '0000'O
|
|
},
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
data_req := {
|
|
l1header := omit,
|
|
l2_payload := l2_data
|
|
}
|
|
}
|
|
}
|
|
|
|
template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ_SACCH(template (value) RslChannelNr chan_nr,
|
|
template (value) RslLinkId link_id,
|
|
template (value) SacchL1Header l1h,
|
|
octetstring l2_data) := {
|
|
header := ts_L1ctlHeader(L1CTL_DATA_REQ),
|
|
ul_info := {
|
|
chan_nr := chan_nr,
|
|
link_id := link_id,
|
|
padding := '0000'O
|
|
},
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
data_req := {
|
|
l1header := l1h,
|
|
l2_payload := l2_data
|
|
}
|
|
}
|
|
}
|
|
|
|
template (value) L1ctlUlMessage ts_L1CTL_TRAFFIC_REQ(template (value) RslChannelNr chan_nr,
|
|
template (value) RslLinkId link_id,
|
|
octetstring frame) := {
|
|
header := ts_L1ctlHeader(L1CTL_TRAFFIC_REQ),
|
|
ul_info := {
|
|
chan_nr := chan_nr,
|
|
link_id := link_id,
|
|
padding := '0000'O
|
|
},
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
traffic_req := {
|
|
data := frame
|
|
}
|
|
}
|
|
};
|
|
|
|
template (value) L1ctlUlMessage ts_L1CTL_TBF_CFG_REQ(boolean is_uplink, TfiUsfArr tfi_usf) := {
|
|
header := ts_L1ctlHeader(L1CTL_TBF_CFG_REQ),
|
|
ul_info := omit,
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
tbf_cfg_req := {
|
|
tbf_nr := 0,
|
|
is_uplink := is_uplink,
|
|
padding := '0000'O,
|
|
tfi_usf := tfi_usf
|
|
}
|
|
}
|
|
};
|
|
|
|
template L1ctlDlMessage tr_L1CTL_TBF_CFG_CONF(template boolean is_uplink) := {
|
|
header := tr_L1ctlHeader(L1CTL_TBF_CFG_CONF),
|
|
dl_info := omit,
|
|
payload := {
|
|
tbf_cfg_conf := {
|
|
tbf_nr := 0,
|
|
is_uplink := is_uplink,
|
|
padding := ?,
|
|
tfi_usf := ?
|
|
}
|
|
}
|
|
};
|
|
|
|
template (value) L1ctlUlMessage ts_L1CTL_DATA_TBF_REQ(octetstring l2_data,
|
|
L1ctlGprsCs cs := L1CTL_CS1,
|
|
uint8_t tbf_nr := 0) := {
|
|
header := ts_L1ctlHeader(L1CTL_DATA_TBF_REQ),
|
|
ul_info := omit,
|
|
ul_info_tbf := {
|
|
tbf_nr := tbf_nr,
|
|
cs := cs,
|
|
padding := '0000'O
|
|
},
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
other := l2_data
|
|
}
|
|
}
|
|
|
|
template (value) L1ctlUlMessage ts_L1CTL_DATA_ABS_REQ(octetstring l2_data, Arfcn arfcn,
|
|
uint8_t ts, GsmFrameNumber fn,
|
|
L1ctlGprsCs cs := L1CTL_CS1,
|
|
uint8_t tbf_nr := 0) := {
|
|
header := ts_L1ctlHeader(L1CTL_DATA_ABS_REQ),
|
|
ul_info := omit,
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := {
|
|
tbf_nr := tbf_nr,
|
|
cs := cs,
|
|
ts_nr := ts,
|
|
padding := '00'O,
|
|
fn := fn,
|
|
arfcn := arfcn,
|
|
padding2 := '0000'O
|
|
},
|
|
payload := {
|
|
other := l2_data
|
|
}
|
|
}
|
|
|
|
|
|
/* for matching against incoming RACH_CONF */
|
|
template L1ctlDlMessage tr_L1CTL_RACH_CONF := {
|
|
header := tr_L1ctlHeader(L1CTL_RACH_CONF),
|
|
dl_info := ?,
|
|
payload := *
|
|
};
|
|
|
|
/* for matching against incoming DATA_IND */
|
|
template L1ctlDlMessage tr_L1CTL_DATA_IND(template RslChannelNr chan_nr,
|
|
template RslLinkId link_id := ?,
|
|
template octetstring l2_data := ?,
|
|
template uint8_t num_biterr := 0,
|
|
template uint8_t fire_crc := 0) := {
|
|
header := tr_L1ctlHeader(L1CTL_DATA_IND),
|
|
dl_info := {
|
|
chan_nr := chan_nr,
|
|
link_id := link_id,
|
|
arfcn := ?,
|
|
frame_nr := ?,
|
|
rx_level := ?,
|
|
snr := ?,
|
|
num_biterr := num_biterr,
|
|
fire_crc := fire_crc
|
|
},
|
|
payload := {
|
|
data_ind := {
|
|
payload := l2_data
|
|
}
|
|
}
|
|
};
|
|
|
|
/* for matching against incoming TRAFFIC_IND */
|
|
template L1ctlDlMessage tr_L1CTL_TRAFFIC_IND(template RslChannelNr chan_nr,
|
|
template RslLinkId link_id := ?,
|
|
template octetstring frame := ?,
|
|
template uint8_t num_biterr := 0,
|
|
template uint8_t fire_crc := 0) := {
|
|
header := tr_L1ctlHeader(L1CTL_TRAFFIC_IND),
|
|
dl_info := {
|
|
chan_nr := chan_nr,
|
|
link_id := link_id,
|
|
arfcn := ?,
|
|
frame_nr := ?,
|
|
rx_level := ?,
|
|
snr := ?,
|
|
num_biterr := num_biterr,
|
|
fire_crc := fire_crc
|
|
},
|
|
payload := {
|
|
traffic_ind := {
|
|
data := frame
|
|
}
|
|
}
|
|
};
|
|
|
|
template (value) L1ctlUlMessage ts_L1CTL_CRYPTO_REQ(RslChannelNr chan_nr, uint8_t algo,
|
|
octetstring key) := {
|
|
header := ts_L1ctlHeader(L1CTL_CRYPTO_REQ),
|
|
ul_info := {
|
|
chan_nr := chan_nr,
|
|
link_id := ts_RslLinkID_DCCH(0),
|
|
padding := '0000'O
|
|
},
|
|
ul_info_tbf := omit,
|
|
ul_info_abs := omit,
|
|
payload := {
|
|
crypto_req := {
|
|
algo := algo,
|
|
key_len := 0, /* overwritten */
|
|
key := key
|
|
}
|
|
}
|
|
};
|
|
|
|
const octetstring c_DummyUI := '0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O;
|
|
|
|
/* We use "BYTEORDER(last)" so we get little-endian integers. Unfortuantely, this also
|
|
switches the byte ordering in octet strings, so we need to explicitly annotate them :/ */
|
|
} with { encode "RAW" };
|