blob: 44f04901498bf1809656d95bd34fa649bea68bba [file] [log] [blame]
Harald Weltef6543322017-07-16 07:35:10 +02001/* Data Types / Encoding / Decoding for OsmocomBB L1CTL interface */
2/* (C) 2017 by Harald Welte <laforge@gnumonks.org>, derived from l1ctl_proto.h
Harald Welte34b5a952019-05-27 11:54:11 +02003 * which is (C) 2010 by Harald Welte + Holger Hans Peter Freyther
4 * All rights reserved.
5 *
6 * Released under the terms of GNU General Public License, Version 2 or
7 * (at your option) any later version.
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
Harald Weltef6543322017-07-16 07:35:10 +020012module L1CTL_Types {
13
14 import from General_Types all;
15 import from GSM_Types all;
Harald Welte9419c8a2017-07-30 04:07:05 +020016 import from GSM_RR_Types all;
Harald Weltef6543322017-07-16 07:35:10 +020017 import from Osmocom_Types all;
18
Harald Welte7024baa2018-03-02 23:37:51 +010019 type uint32_t uint32_le with { variant "BYTEORDER(first)" };
20
Harald Weltef6543322017-07-16 07:35:10 +020021 type enumerated L1ctlMsgType {
22 L1CTL_NONE,
23 L1CTL_FBSB_REQ,
24 L1CTL_FBSB_CONF,
25 L1CTL_DATA_IND,
26 L1CTL_RACH_REQ,
27 L1CTL_DM_EST_REQ,
28 L1CTL_DATA_REQ,
29 L1CTL_RESET_IND,
30 L1CTL_PM_REQ, /* power measurement */
31 L1CTL_PM_CONF, /* power measurement */
32 L1CTL_ECHO_REQ,
33 L1CTL_ECHO_CONF,
34 L1CTL_RACH_CONF,
35 L1CTL_RESET_REQ,
36 L1CTL_RESET_CONF,
37 L1CTL_DATA_CONF,
38 L1CTL_CCCH_MODE_REQ,
39 L1CTL_CCCH_MODE_CONF,
40 L1CTL_DM_REL_REQ,
41 L1CTL_PARAM_REQ,
42 L1CTL_DM_FREQ_REQ,
43 L1CTL_CRYPTO_REQ,
44 L1CTL_SIM_REQ,
45 L1CTL_SIM_CONF,
46 L1CTL_TCH_MODE_REQ,
47 L1CTL_TCH_MODE_CONF,
48 L1CTL_NEIGH_PM_REQ,
49 L1CTL_NEIGH_PM_IND,
50 L1CTL_TRAFFIC_REQ,
51 L1CTL_TRAFFIC_CONF,
Harald Welte00d4dac2017-07-30 00:50:32 +020052 L1CTL_TRAFFIC_IND,
Vadim Yanitskiy4e79ff52019-04-22 06:38:21 +070053 L1CTL_BURST_IND,
Harald Welte00d4dac2017-07-30 00:50:32 +020054 L1CTL_TBF_CFG_REQ,
Harald Welteb3c226e2017-07-30 17:18:01 +020055 L1CTL_TBF_CFG_CONF,
56 L1CTL_DATA_TBF_REQ,
Harald Welte3a40ec72018-03-02 20:45:04 +010057 L1CTL_DATA_TBF_CONF,
Vadim Yanitskiy5c836792019-04-22 05:45:03 +070058 L1CTL_EXT_RACH_REQ,
59 L1CTL_DATA_ABS_REQ /*!< FIXME: no such message in OsmocomBB */
Harald Weltef6543322017-07-16 07:35:10 +020060 } with { variant "FIELDLENGTH(8)" };
61
62 type enumerated L1ctlCcchMode {
63 CCCH_MODE_NONE (0),
64 CCCH_MODE_NON_COMBINED,
Harald Welte990a3612019-05-27 14:02:13 +020065 CCCH_MODE_COMBINED,
66 CCCH_MODE_COMBINED_CBCH
Harald Weltef6543322017-07-16 07:35:10 +020067 } with { variant "FIELDLENGTH(8)" };
68
69 type enumerated L1ctlNeighMode {
70 NEIGH_MODE_NONE (0),
71 NEIGH_MODE_PM,
72 NEIGH_MODE_SB
73 } with { variant "FIELDLENGTH(8)" };
74
Harald Welte1dcc3712017-08-01 00:05:52 +020075 type enumerated L1ctlGprsCs {
76 L1CTL_CS1 (1),
77 L1CTL_CS2,
78 L1CTL_CS3,
79 L1CTL_CS4,
80 L1CTL_MCS1,
81 L1CTL_MCS2,
82 L1CTL_MCS3,
83 L1CTL_MCS4,
84 L1CTL_MCS5,
85 L1CTL_MCS6,
86 L1CTL_MCS7,
87 L1CTL_MCS8,
88 L1CTL_MCS9
89 } with { variant "FIELDLENGTH(8)" };
90
Harald Weltef6543322017-07-16 07:35:10 +020091 type enumerated L1ctlResetType {
92 L1CTL_RES_T_BOOT (0),
93 L1CTL_RES_T_FULL,
94 L1CTL_RES_T_SCHED
95 } with { variant "FIELDLENGTH(8)" };
96
Harald Weltef6543322017-07-16 07:35:10 +020097 type record L1ctlHdrFlags {
98 BIT7 padding,
99 boolean f_done
100 } with { variant "" };
101
102 type record L1ctlHeader {
103 L1ctlMsgType msg_type,
104 L1ctlHdrFlags flags,
105 OCT2 padding
106 } with { variant "" };
107
Harald Weltef8df4cb2018-03-10 15:15:08 +0100108 template L1ctlHeader tr_L1ctlHeader(template L1ctlMsgType msg_type) := {
109 msg_type := msg_type,
110 flags := ?,
111 padding := ?
112 };
113
114 template (value) L1ctlHeader ts_L1ctlHeader(L1ctlMsgType msg_type) := {
Harald Welte52c713c2017-07-16 15:44:44 +0200115 msg_type := msg_type,
116 flags := { padding := '0000000'B, f_done := false },
117 padding := '0000'O
118 };
119
Harald Weltef6543322017-07-16 07:35:10 +0200120 type record L1ctlDlInfo {
Harald Welte8e4db2c2017-07-16 18:54:55 +0200121 RslChannelNr chan_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200122 RslLinkId link_id,
123 Arfcn arfcn,
Harald Welte5f0d5c82017-07-16 18:56:01 +0200124 uint32_t frame_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200125 GsmRxLev rx_level,
126 uint8_t snr,
127 uint8_t num_biterr,
128 uint8_t fire_crc
129 } with { variant "" };
130
131 type record L1ctlFbsbConf {
132 int16_t initial_freq_err,
133 uint8_t result,
134 uint8_t bsic
135 } with { variant "" };
136
137 type record L1ctlCcchModeConf {
138 L1ctlCcchMode ccch_mode,
139 OCT3 padding
140 } with { variant "" };
141
142 /* gsm48_chan_mode */
143 type uint8_t L1ctlTchMode;
144
145 type record L1ctlAudioMode {
146 BIT4 padding,
147 boolean tx_microphone,
148 boolean tx_traffic_req,
149 boolean rx_speaker,
150 boolean rx_traffic_ind
151 } with { variant "" };
152
Harald Weltef8df4cb2018-03-10 15:15:08 +0100153 template (value) L1ctlAudioMode t_L1CTL_AudioModeNone := { '0000'B, false, false, false, false };
Harald Welte66110f02017-07-16 21:05:18 +0200154
Harald Weltef6543322017-07-16 07:35:10 +0200155 type record L1ctlTchModeConf {
156 L1ctlTchMode tch_mode,
157 L1ctlAudioMode audio_mode,
158 OCT2 padding
159 } with { variant "" };
160
161 type record L1ctlDataInd {
Vadim Yanitskiy2a92e2a2019-05-28 21:13:35 +0700162 octetstring payload
Harald Welte7024baa2018-03-02 23:37:51 +0100163 } with {
164 variant (payload) "BYTEORDER(first)"
165 };
Harald Weltef6543322017-07-16 07:35:10 +0200166
167 type union L1ctlDlPayload {
168 L1ctlFbsbConf fbsb_conf,
169 L1ctlCcchModeConf ccch_mode_conf,
170 L1ctlTchModeConf tch_mode_conf,
171 L1ctlDataInd data_ind,
172 L1ctlTrafficReq traffic_ind,
Harald Welte00d4dac2017-07-30 00:50:32 +0200173 L1ctlTbfCfgReq tbf_cfg_conf,
Harald Weltef6543322017-07-16 07:35:10 +0200174 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100175 } with {
176 variant (other) "BYTEORDER(first)"
177 };
Harald Weltef6543322017-07-16 07:35:10 +0200178
179 type record L1ctlDlMessage {
180 L1ctlHeader header,
181 L1ctlDlInfo dl_info optional,
Harald Weltef56cc492018-04-15 10:58:43 +0200182 L1ctlDlPayload payload optional
Harald Weltef6543322017-07-16 07:35:10 +0200183 } with { variant (dl_info) "PRESENCE(header.msg_type = L1CTL_FBSB_CONF,
184 header.msg_type = L1CTL_RACH_CONF,
185 header.msg_type = L1CTL_DATA_IND,
186 header.msg_type = L1CTL_DATA_CONF,
Harald Welte3c4cbf62018-03-30 10:31:39 +0200187 header.msg_type = L1CTL_TRAFFIC_IND,
188 header.msg_type = L1CTL_TRAFFIC_CONF)"
Harald Weltef6543322017-07-16 07:35:10 +0200189 variant (payload) "CROSSTAG(fbsb_conf, header.msg_type = L1CTL_FBSB_CONF;
190 ccch_mode_conf, header.msg_type = L1CTL_CCCH_MODE_CONF;
191 tch_mode_conf, header.msg_type = L1CTL_TCH_MODE_CONF;
192 data_ind, header.msg_type = L1CTL_DATA_IND;
193 traffic_ind, header.msg_type = L1CTL_TRAFFIC_IND;
Harald Welte00d4dac2017-07-30 00:50:32 +0200194 tbf_cfg_conf, header.msg_type = L1CTL_TBF_CFG_CONF;
Harald Weltef6543322017-07-16 07:35:10 +0200195 other, OTHERWISE;
196 )" };
197
198 external function enc_L1ctlDlMessage(in L1ctlDlMessage msg) return octetstring
199 with { extension "prototype(convert) encode(RAW)" };
200 external function dec_L1ctlDlMessage(in octetstring stream) return L1ctlDlMessage
201 with { extension "prototype(convert) decode(RAW)" };
202
203
204 type record L1ctlUlInfo {
Harald Welte8e4db2c2017-07-16 18:54:55 +0200205 RslChannelNr chan_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200206 RslLinkId link_id,
207 OCT2 padding
208 } with { variant "" };
209
Harald Welteb3c226e2017-07-30 17:18:01 +0200210 type record L1ctlUlTbfInfo {
211 uint8_t tbf_nr,
Harald Welte1dcc3712017-08-01 00:05:52 +0200212 L1ctlGprsCs cs,
213 OCT2 padding
Harald Welteb3c226e2017-07-30 17:18:01 +0200214 } with { variant "" };
215
Harald Welte3a40ec72018-03-02 20:45:04 +0100216 type record L1ctlUlAbsInfo {
217 uint8_t tbf_nr,
218 L1ctlGprsCs cs,
219 uint8_t ts_nr,
220 OCT1 padding,
Harald Welte7024baa2018-03-02 23:37:51 +0100221 uint32_le fn,
Harald Welte3a40ec72018-03-02 20:45:04 +0100222 Arfcn arfcn,
223 OCT2 padding2
224 } with { variant "" };
225
Harald Weltef6543322017-07-16 07:35:10 +0200226 type record L1ctlFbsbFlags {
227 BIT5 padding,
228 boolean sb,
229 boolean fb1,
230 boolean fb0
Harald Welte344c0cf2018-03-09 16:17:45 +0100231 } with { variant "FIELDORDER(msb)" };
Harald Weltef6543322017-07-16 07:35:10 +0200232
Harald Weltef8df4cb2018-03-10 15:15:08 +0100233 template (value) L1ctlFbsbFlags t_L1CTL_FBSB_F_ALL := {
Harald Welte66110f02017-07-16 21:05:18 +0200234 padding := '00000'B,
235 sb := true,
236 fb1 := true,
237 fb0 := true
238 };
239
Harald Weltef6543322017-07-16 07:35:10 +0200240 type record L1ctlFbsbReq {
241 Arfcn arfcn,
242 uint16_t timeout_tdma_frames,
243 uint16_t freq_err_thresh1,
244 uint16_t freq_err_thresh2,
245 uint8_t num_freqerr_avg,
246 L1ctlFbsbFlags flags,
247 uint8_t sync_info_idx,
248 L1ctlCcchMode ccch_mode,
249 GsmRxLev rxlev_exp
250 } with { variant "" };
251
252 type record L1ctlCcchModeReq {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100253 L1ctlCcchMode ccch_mode,
254 OCT3 padding
Harald Weltef6543322017-07-16 07:35:10 +0200255 } with { variant "" };
256
257 type record L1ctlTchModeReq {
258 L1ctlTchMode tch_mode,
259 L1ctlAudioMode audio_mode,
260 OCT2 padding
261 } with { variant "" };
262
263 type record L1ctlRachReq {
264 uint8_t ra,
265 uint8_t combined,
266 uint16_t offset
267 } with { variant "" };
268
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700269 type enumerated L1ctlRachSynchSeq {
270 RACH_SYNCH_SEQ_TS0 (0),
271 RACH_SYNCH_SEQ_TS1,
272 RACH_SYNCH_SEQ_TS2
273 } with { variant "FIELDLENGTH(8)" };
274
275 type record L1ctlExtRachReq {
276 uint16_t ra11,
277 L1ctlRachSynchSeq synch_seq,
278 uint8_t combined,
279 uint16_t offset
280 } with { variant "" };
281
Harald Weltef6543322017-07-16 07:35:10 +0200282 type record L1ctlParReq {
283 int8_t ta,
284 uint8_t tx_power,
285 OCT2 padding
286 } with { variant "" };
287
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200288 type record L1ctlDataReq {
289 SacchL1Header l1header optional,
290 octetstring l2_payload
291 } with { variant "" };
292
Vadim Yanitskiye8ea3ee2020-05-27 13:29:48 +0700293 type record length(0..64) of Arfcn L1ctlMA;
Harald Weltef6543322017-07-16 07:35:10 +0200294 type record L1ctlH1 {
295 uint8_t hsn,
296 uint8_t maio,
297 uint8_t n,
Vadim Yanitskiye8ea3ee2020-05-27 13:29:48 +0700298 OCT1 spare,
299 L1ctlMA ma,
300 octetstring padding
301 } with {
302 variant (n) "LENGTHTO(ma)"
303 variant (n) "UNIT(elements)"
304 /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=562849.
305 * TL;DR The reference point of the PADDING attribute is the beginning
306 * of the message, not the beginning of the type/field it's applied on.
307 * Therefore we cannot use it here, and have to add padding manually.
308 * variant (ma) "PADDING(128)" */
309 };
Harald Weltef6543322017-07-16 07:35:10 +0200310
311 type record L1ctlDmEstReq {
312 GsmTsc tsc,
313 uint8_t h,
314 Arfcn arfcn optional,
315 L1ctlH1 hopping optional,
316 L1ctlTchMode tch_mode,
317 L1ctlAudioMode audio_mode
318 } with { variant (arfcn) "PRESENCE(h = 0)"
319 variant (hopping) "PRESENCE(h = 1)" };
320
321 type record L1ctlReset {
322 L1ctlResetType reset_type,
323 OCT3 padding
324 } with { variant "" };
325
Harald Weltee613f962018-04-18 22:38:16 +0200326 type record L1CtlCryptoReq {
327 uint8_t algo,
328 uint8_t key_len,
329 octetstring key
330 } with { variant (key_len) "LENGTHTO(key)" };
331
Harald Weltef6543322017-07-16 07:35:10 +0200332
333 type record L1ctlTrafficReq {
Vadim Yanitskiye01691d2018-10-29 00:18:04 +0700334 octetstring data
Harald Welte7024baa2018-03-02 23:37:51 +0100335 } with {
336 variant (data) "BYTEORDER(first)"
337 }
Harald Weltef6543322017-07-16 07:35:10 +0200338
Harald Welte00d4dac2017-07-30 00:50:32 +0200339 type record length(8) of uint8_t TfiUsfArr;
340
341 type record L1ctlTbfCfgReq {
342 uint8_t tbf_nr,
343 boolean is_uplink,
344 OCT2 padding,
345 TfiUsfArr tfi_usf
346 } with { variant (is_uplink) "FIELDLENGTH(8)" };
347
Harald Weltef6543322017-07-16 07:35:10 +0200348 type union L1ctlUlPayload {
349 L1ctlFbsbReq fbsb_req,
350 L1ctlCcchModeReq ccch_mode_req,
351 L1ctlTchModeReq tch_mode_req,
352 L1ctlRachReq rach_req,
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700353 L1ctlExtRachReq ext_rach_req,
Harald Weltef6543322017-07-16 07:35:10 +0200354 L1ctlParReq par_req,
355 L1ctlDmEstReq dm_est_req,
356 L1ctlReset reset_req,
357 //L1ctlNeighPmReq neigh_pm_req,
Harald Weltee613f962018-04-18 22:38:16 +0200358 L1CtlCryptoReq crypto_req,
Harald Weltef6543322017-07-16 07:35:10 +0200359 L1ctlTrafficReq traffic_req,
Harald Welte00d4dac2017-07-30 00:50:32 +0200360 L1ctlTbfCfgReq tbf_cfg_req,
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200361 L1ctlDataReq data_req,
Harald Weltef6543322017-07-16 07:35:10 +0200362 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100363 } with {
364 variant (other) "BYTEORDER(first)"
365 };
Harald Weltef6543322017-07-16 07:35:10 +0200366
367 type record L1ctlUlMessage {
368 L1ctlHeader header,
369 L1ctlUlInfo ul_info optional,
Harald Welteb3c226e2017-07-30 17:18:01 +0200370 L1ctlUlTbfInfo ul_info_tbf optional,
Harald Welte3a40ec72018-03-02 20:45:04 +0100371 L1ctlUlAbsInfo ul_info_abs optional,
Harald Weltef6543322017-07-16 07:35:10 +0200372 L1ctlUlPayload payload
373 } with { variant (ul_info) "PRESENCE(header.msg_type = L1CTL_RACH_REQ,
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700374 header.msg_type = L1CTL_EXT_RACH_REQ,
Harald Weltef6543322017-07-16 07:35:10 +0200375 header.msg_type = L1CTL_PARAM_REQ,
376 header.msg_type = L1CTL_CRYPTO_REQ,
377 header.msg_type = L1CTL_DATA_REQ,
378 header.msg_type = L1CTL_DM_EST_REQ,
379 header.msg_type = L1CTL_DM_FREQ_REQ,
380 header.msg_type = L1CTL_DM_REL_REQ,
381 header.msg_type = L1CTL_TRAFFIC_REQ)"
Harald Welteb3c226e2017-07-30 17:18:01 +0200382 variant (ul_info_tbf) "PRESENCE(header.msg_type = L1CTL_DATA_TBF_REQ)"
Harald Welte3a40ec72018-03-02 20:45:04 +0100383 variant (ul_info_abs) "PRESENCE(header.msg_type = L1CTL_DATA_ABS_REQ)"
Harald Weltef6543322017-07-16 07:35:10 +0200384 variant (payload) "CROSSTAG(fbsb_req, header.msg_type = L1CTL_FBSB_REQ;
385 ccch_mode_req, header.msg_type = L1CTL_CCCH_MODE_REQ;
386 tch_mode_req, header.msg_type = L1CTL_TCH_MODE_REQ;
387 rach_req, header.msg_type = L1CTL_RACH_REQ;
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700388 ext_rach_req, header.msg_type = L1CTL_EXT_RACH_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200389 par_req, header.msg_type = L1CTL_PARAM_REQ;
390 dm_est_req, header.msg_type = L1CTL_DM_EST_REQ;
391 reset_req, header.msg_type = L1CTL_RESET_REQ;
Harald Weltee613f962018-04-18 22:38:16 +0200392 crypto_req, header.msg_type = L1CTL_CRYPTO_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200393 traffic_req, header.msg_type = L1CTL_TRAFFIC_REQ;
Harald Welte00d4dac2017-07-30 00:50:32 +0200394 tbf_cfg_req, header.msg_type = L1CTL_TBF_CFG_REQ;
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200395 data_req, header.msg_type = L1CTL_DATA_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200396 other, OTHERWISE;
397 )" };
398
399 external function enc_L1ctlUlMessage(in L1ctlUlMessage msg) return octetstring
400 with { extension "prototype(convert) encode(RAW)" };
401 external function dec_L1ctlUlMessage(in octetstring stream) return L1ctlUlMessage
402 with { extension "prototype(convert) decode(RAW)" };
403
Harald Welte52c713c2017-07-16 15:44:44 +0200404 type record L1ctlUlMessageLV {
405 uint16_t len,
406 L1ctlUlMessage msg
407 } with { variant (len) "LENGTHTO(msg)" };
408
409 external function enc_L1ctlUlMessageLV(in L1ctlUlMessageLV msg) return octetstring
410 with { extension "prototype(convert) encode(RAW)" };
411 external function dec_L1ctlUlMessageLV(in octetstring stream) return L1ctlUlMessageLV
412 with { extension "prototype(convert) decode(RAW)" };
413
414 type record L1ctlDlMessageLV {
415 uint16_t len,
416 L1ctlDlMessage msg
417 } with { variant (len) "LENGTHTO(msg)" };
418
419 external function enc_L1ctlDlMessageLV(in L1ctlDlMessageLV msg) return octetstring
420 with { extension "prototype(convert) encode(RAW)" };
421 external function dec_L1ctlDlMessageLV(in octetstring stream) return L1ctlDlMessageLV
422 with { extension "prototype(convert) decode(RAW)" };
423
424
Harald Welte9e4725d2017-07-16 23:18:09 +0200425
426
427 /* for generating RESET_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100428 template (value) L1ctlUlMessage t_L1ctlResetReq(L1ctlResetType rst_type) := {
429 header := ts_L1ctlHeader(L1CTL_RESET_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200430 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200431 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100432 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200433 payload := {
434 reset_req := {
435 reset_type := rst_type,
436 padding := '000000'O
437 }
438 }
439 };
440
441 /* for generating FBSB_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100442 template (value) L1ctlUlMessage ts_L1CTL_FBSB_REQ(Arfcn arfcn, L1ctlFbsbFlags flags,
443 uint8_t sync_info_idx,
444 L1ctlCcchMode ccch_mode,
445 GsmRxLev rxlev_exp) := {
446 header := ts_L1ctlHeader(L1CTL_FBSB_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200447 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200448 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100449 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200450 payload := {
451 fbsb_req := {
452 arfcn := arfcn,
Harald Weltea82f7e62018-02-22 18:51:33 +0100453 timeout_tdma_frames := 250, /* about 1s */
Harald Welte9e4725d2017-07-16 23:18:09 +0200454 freq_err_thresh1 := 10000,
455 freq_err_thresh2 := 800,
456 num_freqerr_avg := 3,
457 flags := flags,
458 sync_info_idx := sync_info_idx,
459 ccch_mode := ccch_mode,
460 rxlev_exp := rxlev_exp
461 }
462 }
463 };
464
465 /* for matching against incoming FBSB_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100466 template L1ctlDlMessage tr_L1CTL_FBSB_CONF(template uint8_t result) := {
467 header := tr_L1ctlHeader(L1CTL_FBSB_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200468 dl_info := ?,
469 payload := {
470 fbsb_conf := {
471 initial_freq_err := ?,
472 result := result,
473 bsic := ?
474 }
475 }
476 };
477
Harald Weltef8df4cb2018-03-10 15:15:08 +0100478 template (value) L1ctlUlMessage ts_L1CTL_CCCH_MODE_REQ(L1ctlCcchMode ccch_mode) := {
479 header := ts_L1ctlHeader(L1CTL_CCCH_MODE_REQ),
480 ul_info := omit,
481 ul_info_tbf := omit,
482 ul_info_abs := omit,
483 payload := {
484 ccch_mode_req := {
485 ccch_mode := ccch_mode,
486 padding := '000000'O
487 }
488 }
489 };
490
Harald Welte3757e602018-03-10 17:12:02 +0100491
492 template L1ctlDlMessage tr_L1CTL_MsgType(template L1ctlMsgType msg_type) := {
493 header := tr_L1ctlHeader(msg_type),
494 dl_info := *,
Harald Weltef56cc492018-04-15 10:58:43 +0200495 payload := *
Harald Welte3757e602018-03-10 17:12:02 +0100496 }
497
498 template L1ctlDlMessage tr_L1CTL_CCCH_MODE_CONF := tr_L1CTL_MsgType(L1CTL_CCCH_MODE_CONF);
Harald Weltef8df4cb2018-03-10 15:15:08 +0100499
Vadim Yanitskiye432ba92019-05-31 18:44:13 +0700500 template L1ctlUlMessage ts_L1CTL_RACH_REQ(uint8_t ra, uint8_t combined, uint16_t offset,
501 template (value) RslChannelNr chan_nr := ts_RslChanNr_RACH(0),
502 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0)) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100503 header := ts_L1ctlHeader(L1CTL_RACH_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200504 ul_info := {
Vadim Yanitskiye432ba92019-05-31 18:44:13 +0700505 chan_nr := chan_nr,
506 link_id := link_id,
Harald Welte9e4725d2017-07-16 23:18:09 +0200507 padding := '0000'O
508 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200509 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100510 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200511 payload := {
512 rach_req := {
513 ra := ra,
514 combined := combined,
515 offset := offset
516 }
517 }
518 }
519
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700520 template L1ctlUlMessage ts_L1CTL_EXT_RACH_REQ(
521 uint16_t ra11, L1ctlRachSynchSeq seq,
522 uint8_t combined, uint16_t offset
523 ) := {
524 header := ts_L1ctlHeader(L1CTL_EXT_RACH_REQ),
525 ul_info := {
526 /* FIXME: both RSL chan_nr and link_id should be configurable */
527 chan_nr := t_RslChanNr_RACH(0),
528 link_id := ts_RslLinkID_DCCH(0),
529 padding := '0000'O
530 },
531 ul_info_tbf := omit,
532 ul_info_abs := omit,
533 payload := {
534 ext_rach_req := {
535 ra11 := ra11,
536 synch_seq := seq,
537 combined := combined,
538 offset := offset
539 }
540 }
541 }
542
Harald Weltef8df4cb2018-03-10 15:15:08 +0100543 template L1ctlUlMessage ts_L1CTL_PAR_REQ(uint8_t ta, uint8_t tx_power) := {
544 header := ts_L1ctlHeader(L1CTL_PARAM_REQ),
Harald Welte37052732018-03-09 19:38:46 +0100545 ul_info := {
546 chan_nr := t_RslChanNr_RACH(0),
547 link_id := ts_RslLinkID_DCCH(0),
548 padding := '0000'O
549 },
550 ul_info_tbf := omit,
551 ul_info_abs := omit,
552 payload := {
553 par_req := {
554 ta := ta,
555 tx_power := tx_power,
556 padding := '0000'O
557 }
558 }
559 }
560
Vadim Yanitskiy5afe8852020-05-27 14:40:51 +0700561 /* Base template to be inherited by ts_L1CTL_DM_EST_REQ_H0 and ts_L1CTL_DM_EST_REQ_H1 */
562 private template (value) L1ctlUlMessage ts_L1CTL_DM_EST_REQ(template (value) RslChannelNr chan_nr,
563 template (value) GsmTsc tsc) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100564 header := ts_L1ctlHeader(L1CTL_DM_EST_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200565 ul_info := {
566 chan_nr := chan_nr,
567 link_id := ts_RslLinkID_DCCH(0),
568 padding := '0000'O
569 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200570 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100571 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200572 payload := {
573 dm_est_req := {
574 tsc := tsc,
Harald Welte9e4725d2017-07-16 23:18:09 +0200575 tch_mode := 0,
576 audio_mode := t_L1CTL_AudioModeNone
577 }
578 }
579 }
580
Vadim Yanitskiy5afe8852020-05-27 14:40:51 +0700581 template (value) L1ctlUlMessage ts_L1CTL_DM_EST_REQ_H0(template (value) RslChannelNr chan_nr,
582 template (value) GsmTsc tsc,
583 template (value) GsmArfcn arfcn)
584 modifies ts_L1CTL_DM_EST_REQ := {
585 payload := {
586 dm_est_req := {
587 h := 0,
588 arfcn := { false, arfcn },
589 hopping := omit
590 }
591 }
592 }
593
Vadim Yanitskiyeda90812020-05-27 14:51:18 +0700594 template (value) L1ctlUlMessage ts_L1CTL_DM_EST_REQ_H1(template (value) RslChannelNr chan_nr,
595 template (value) GsmTsc tsc,
596 template (value) uint6_t hsn,
597 template (value) uint6_t maio,
598 template (value) L1ctlMA ma)
599 modifies ts_L1CTL_DM_EST_REQ := {
600 payload := {
601 dm_est_req := {
602 h := 1,
603 arfcn := omit,
604 hopping := {
605 hsn := hsn,
606 maio := maio,
607 n := sizeof(ma),
608 spare := '00'O,
609 ma := ma,
610 /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=562849 */
611 padding := f_pad_oct(''O, (64 - sizeof(ma)) * 2, '00'O)
612 }
613 }
614 }
615 }
616
Harald Weltef8df4cb2018-03-10 15:15:08 +0100617 template L1ctlUlMessage ts_L1CTL_DM_REL_REQ(RslChannelNr chan_nr) := {
618 header := ts_L1ctlHeader(L1CTL_DM_REL_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200619 ul_info := {
620 chan_nr := chan_nr,
621 link_id := ts_RslLinkID_DCCH(0),
622 padding := '0000'O
623 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200624 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100625 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200626 payload := {
627 other := ''O
628 }
629 }
630
Harald Weltef8df4cb2018-03-10 15:15:08 +0100631 template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ(template (value) RslChannelNr chan_nr,
632 template (value) RslLinkId link_id,
633 octetstring l2_data) := {
634 header := ts_L1ctlHeader(L1CTL_DATA_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200635 ul_info := {
636 chan_nr := chan_nr,
637 link_id := link_id,
638 padding := '0000'O
639 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200640 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100641 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200642 payload := {
Vadim Yanitskiy0a8d6da2019-05-28 22:18:28 +0700643 data_req := {
644 l1header := omit,
645 l2_payload := l2_data
646 }
Harald Welte9e4725d2017-07-16 23:18:09 +0200647 }
648 }
649
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200650 template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ_SACCH(template (value) RslChannelNr chan_nr,
651 template (value) RslLinkId link_id,
Vadim Yanitskiy0a8d6da2019-05-28 22:18:28 +0700652 template (value) SacchL1Header l1h,
653 octetstring l2_data) := {
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200654 header := ts_L1ctlHeader(L1CTL_DATA_REQ),
655 ul_info := {
656 chan_nr := chan_nr,
657 link_id := link_id,
658 padding := '0000'O
659 },
660 ul_info_tbf := omit,
661 ul_info_abs := omit,
662 payload := {
Vadim Yanitskiy0a8d6da2019-05-28 22:18:28 +0700663 data_req := {
664 l1header := l1h,
665 l2_payload := l2_data
666 }
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200667 }
668 }
669
Vadim Yanitskiyf3cc6492019-06-30 16:34:30 +0700670 template (value) L1ctlUlMessage ts_L1CTL_TRAFFIC_REQ(template (value) RslChannelNr chan_nr,
671 template (value) RslLinkId link_id,
672 octetstring frame) := {
673 header := ts_L1ctlHeader(L1CTL_TRAFFIC_REQ),
674 ul_info := {
675 chan_nr := chan_nr,
676 link_id := link_id,
677 padding := '0000'O
678 },
679 ul_info_tbf := omit,
680 ul_info_abs := omit,
681 payload := {
682 traffic_req := {
683 data := frame
684 }
685 }
686 };
687
Harald Weltef8df4cb2018-03-10 15:15:08 +0100688 template (value) L1ctlUlMessage ts_L1CTL_TBF_CFG_REQ(boolean is_uplink, TfiUsfArr tfi_usf) := {
689 header := ts_L1ctlHeader(L1CTL_TBF_CFG_REQ),
Harald Welte00d4dac2017-07-30 00:50:32 +0200690 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200691 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100692 ul_info_abs := omit,
Harald Welte00d4dac2017-07-30 00:50:32 +0200693 payload := {
694 tbf_cfg_req := {
695 tbf_nr := 0,
696 is_uplink := is_uplink,
697 padding := '0000'O,
698 tfi_usf := tfi_usf
699 }
700 }
701 };
702
Harald Weltef8df4cb2018-03-10 15:15:08 +0100703 template L1ctlDlMessage tr_L1CTL_TBF_CFG_CONF(template boolean is_uplink) := {
704 header := tr_L1ctlHeader(L1CTL_TBF_CFG_CONF),
Harald Welte00d4dac2017-07-30 00:50:32 +0200705 dl_info := omit,
706 payload := {
707 tbf_cfg_conf := {
708 tbf_nr := 0,
709 is_uplink := is_uplink,
710 padding := ?,
711 tfi_usf := ?
712 }
713 }
714 };
715
Harald Weltef8df4cb2018-03-10 15:15:08 +0100716 template (value) L1ctlUlMessage ts_L1CTL_DATA_TBF_REQ(octetstring l2_data,
717 L1ctlGprsCs cs := L1CTL_CS1,
718 uint8_t tbf_nr := 0) := {
719 header := ts_L1ctlHeader(L1CTL_DATA_TBF_REQ),
Harald Welteb3c226e2017-07-30 17:18:01 +0200720 ul_info := omit,
721 ul_info_tbf := {
722 tbf_nr := tbf_nr,
Harald Welte1dcc3712017-08-01 00:05:52 +0200723 cs := cs,
724 padding := '0000'O
Harald Welteb3c226e2017-07-30 17:18:01 +0200725 },
Harald Welte3a40ec72018-03-02 20:45:04 +0100726 ul_info_abs := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200727 payload := {
728 other := l2_data
729 }
730 }
731
Harald Weltef8df4cb2018-03-10 15:15:08 +0100732 template (value) L1ctlUlMessage ts_L1CTL_DATA_ABS_REQ(octetstring l2_data, Arfcn arfcn,
Harald Welte3a40ec72018-03-02 20:45:04 +0100733 uint8_t ts, GsmFrameNumber fn,
734 L1ctlGprsCs cs := L1CTL_CS1,
735 uint8_t tbf_nr := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100736 header := ts_L1ctlHeader(L1CTL_DATA_ABS_REQ),
Harald Welte3a40ec72018-03-02 20:45:04 +0100737 ul_info := omit,
738 ul_info_tbf := omit,
739 ul_info_abs := {
740 tbf_nr := tbf_nr,
741 cs := cs,
742 ts_nr := ts,
743 padding := '00'O,
744 fn := fn,
745 arfcn := arfcn,
746 padding2 := '0000'O
747 },
748 payload := {
749 other := l2_data
750 }
751 }
752
753
Harald Welte9e4725d2017-07-16 23:18:09 +0200754 /* for matching against incoming RACH_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100755 template L1ctlDlMessage tr_L1CTL_RACH_CONF := {
756 header := tr_L1ctlHeader(L1CTL_RACH_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200757 dl_info := ?,
Harald Weltef56cc492018-04-15 10:58:43 +0200758 payload := *
Harald Welte9e4725d2017-07-16 23:18:09 +0200759 };
760
Harald Weltece6dc442018-02-21 22:00:21 +0100761 /* for matching against incoming DATA_IND */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100762 template L1ctlDlMessage tr_L1CTL_DATA_IND(template RslChannelNr chan_nr,
Harald Welte68e495b2018-02-25 00:05:57 +0100763 template RslLinkId link_id := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100764 template octetstring l2_data := ?,
765 template uint8_t num_biterr := 0,
766 template uint8_t fire_crc := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100767 header := tr_L1ctlHeader(L1CTL_DATA_IND),
Harald Welte9e4725d2017-07-16 23:18:09 +0200768 dl_info := {
769 chan_nr := chan_nr,
Harald Weltece6dc442018-02-21 22:00:21 +0100770 link_id := link_id,
Harald Welte9e4725d2017-07-16 23:18:09 +0200771 arfcn := ?,
772 frame_nr := ?,
773 rx_level := ?,
774 snr := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100775 num_biterr := num_biterr,
776 fire_crc := fire_crc
Harald Welte9e4725d2017-07-16 23:18:09 +0200777 },
778 payload := {
Harald Welte68e495b2018-02-25 00:05:57 +0100779 data_ind := {
780 payload := l2_data
781 }
Harald Welte9e4725d2017-07-16 23:18:09 +0200782 }
783 };
784
Vadim Yanitskiyf3cc6492019-06-30 16:34:30 +0700785 /* for matching against incoming TRAFFIC_IND */
786 template L1ctlDlMessage tr_L1CTL_TRAFFIC_IND(template RslChannelNr chan_nr,
787 template RslLinkId link_id := ?,
788 template octetstring frame := ?,
789 template uint8_t num_biterr := 0,
790 template uint8_t fire_crc := 0) := {
791 header := tr_L1ctlHeader(L1CTL_TRAFFIC_IND),
792 dl_info := {
793 chan_nr := chan_nr,
794 link_id := link_id,
795 arfcn := ?,
796 frame_nr := ?,
797 rx_level := ?,
798 snr := ?,
799 num_biterr := num_biterr,
800 fire_crc := fire_crc
801 },
802 payload := {
803 traffic_ind := {
804 data := frame
805 }
806 }
807 };
808
Harald Weltee613f962018-04-18 22:38:16 +0200809 template (value) L1ctlUlMessage ts_L1CTL_CRYPTO_REQ(RslChannelNr chan_nr, uint8_t algo,
810 octetstring key) := {
811 header := ts_L1ctlHeader(L1CTL_CRYPTO_REQ),
812 ul_info := {
813 chan_nr := chan_nr,
814 link_id := ts_RslLinkID_DCCH(0),
815 padding := '0000'O
816 },
817 ul_info_tbf := omit,
818 ul_info_abs := omit,
819 payload := {
820 crypto_req := {
821 algo := algo,
822 key_len := 0, /* overwritten */
823 key := key
824 }
825 }
826 };
827
Harald Welte68e495b2018-02-25 00:05:57 +0100828 const octetstring c_DummyUI := '0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O;
829
Harald Welte7024baa2018-03-02 23:37:51 +0100830/* We use "BYTEORDER(last)" so we get little-endian integers. Unfortuantely, this also
831 switches the byte ordering in octet strings, so we need to explicitly annotate them :/ */
Harald Weltef6543322017-07-16 07:35:10 +0200832} with { encode "RAW" };