blob: 5c90966504855a243948d0d89aca712285dcbaf9 [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 */
Vadim Yanitskiyfe052962020-10-19 13:27:09 +0700143 type enumerated L1ctlTchMode {
144 L1CTL_CHAN_MODE_SIGN ('00000000'B), /* Signalling */
145 L1CTL_CHAN_MODE_SPEECH_V1 ('00000001'B), /* FR or HR codec */
146 L1CTL_CHAN_MODE_SPEECH_V2 ('00100001'B), /* EFR codec */
147 L1CTL_CHAN_MODE_SPEECH_V3 ('01000001'B) /* AMR codec */
148 /* Other modes are not supported for now */
149 } with { variant "FIELDLENGTH(8)" };
Harald Weltef6543322017-07-16 07:35:10 +0200150
151 type record L1ctlAudioMode {
152 BIT4 padding,
153 boolean tx_microphone,
154 boolean tx_traffic_req,
155 boolean rx_speaker,
156 boolean rx_traffic_ind
157 } with { variant "" };
158
Harald Weltef8df4cb2018-03-10 15:15:08 +0100159 template (value) L1ctlAudioMode t_L1CTL_AudioModeNone := { '0000'B, false, false, false, false };
Harald Welte66110f02017-07-16 21:05:18 +0200160
Harald Weltef6543322017-07-16 07:35:10 +0200161 type record L1ctlTchModeConf {
162 L1ctlTchMode tch_mode,
163 L1ctlAudioMode audio_mode,
164 OCT2 padding
165 } with { variant "" };
166
167 type record L1ctlDataInd {
Vadim Yanitskiy2a92e2a2019-05-28 21:13:35 +0700168 octetstring payload
Harald Welte7024baa2018-03-02 23:37:51 +0100169 } with {
170 variant (payload) "BYTEORDER(first)"
171 };
Harald Weltef6543322017-07-16 07:35:10 +0200172
173 type union L1ctlDlPayload {
174 L1ctlFbsbConf fbsb_conf,
175 L1ctlCcchModeConf ccch_mode_conf,
176 L1ctlTchModeConf tch_mode_conf,
177 L1ctlDataInd data_ind,
178 L1ctlTrafficReq traffic_ind,
Harald Welte00d4dac2017-07-30 00:50:32 +0200179 L1ctlTbfCfgReq tbf_cfg_conf,
Harald Weltef6543322017-07-16 07:35:10 +0200180 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100181 } with {
182 variant (other) "BYTEORDER(first)"
183 };
Harald Weltef6543322017-07-16 07:35:10 +0200184
185 type record L1ctlDlMessage {
186 L1ctlHeader header,
187 L1ctlDlInfo dl_info optional,
Harald Weltef56cc492018-04-15 10:58:43 +0200188 L1ctlDlPayload payload optional
Harald Weltef6543322017-07-16 07:35:10 +0200189 } with { variant (dl_info) "PRESENCE(header.msg_type = L1CTL_FBSB_CONF,
190 header.msg_type = L1CTL_RACH_CONF,
191 header.msg_type = L1CTL_DATA_IND,
192 header.msg_type = L1CTL_DATA_CONF,
Harald Welte3c4cbf62018-03-30 10:31:39 +0200193 header.msg_type = L1CTL_TRAFFIC_IND,
194 header.msg_type = L1CTL_TRAFFIC_CONF)"
Harald Weltef6543322017-07-16 07:35:10 +0200195 variant (payload) "CROSSTAG(fbsb_conf, header.msg_type = L1CTL_FBSB_CONF;
196 ccch_mode_conf, header.msg_type = L1CTL_CCCH_MODE_CONF;
197 tch_mode_conf, header.msg_type = L1CTL_TCH_MODE_CONF;
198 data_ind, header.msg_type = L1CTL_DATA_IND;
199 traffic_ind, header.msg_type = L1CTL_TRAFFIC_IND;
Harald Welte00d4dac2017-07-30 00:50:32 +0200200 tbf_cfg_conf, header.msg_type = L1CTL_TBF_CFG_CONF;
Harald Weltef6543322017-07-16 07:35:10 +0200201 other, OTHERWISE;
202 )" };
203
204 external function enc_L1ctlDlMessage(in L1ctlDlMessage msg) return octetstring
205 with { extension "prototype(convert) encode(RAW)" };
206 external function dec_L1ctlDlMessage(in octetstring stream) return L1ctlDlMessage
207 with { extension "prototype(convert) decode(RAW)" };
208
209
210 type record L1ctlUlInfo {
Harald Welte8e4db2c2017-07-16 18:54:55 +0200211 RslChannelNr chan_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200212 RslLinkId link_id,
213 OCT2 padding
214 } with { variant "" };
215
Harald Welteb3c226e2017-07-30 17:18:01 +0200216 type record L1ctlUlTbfInfo {
217 uint8_t tbf_nr,
Harald Welte1dcc3712017-08-01 00:05:52 +0200218 L1ctlGprsCs cs,
219 OCT2 padding
Harald Welteb3c226e2017-07-30 17:18:01 +0200220 } with { variant "" };
221
Harald Welte3a40ec72018-03-02 20:45:04 +0100222 type record L1ctlUlAbsInfo {
223 uint8_t tbf_nr,
224 L1ctlGprsCs cs,
225 uint8_t ts_nr,
226 OCT1 padding,
Harald Welte7024baa2018-03-02 23:37:51 +0100227 uint32_le fn,
Harald Welte3a40ec72018-03-02 20:45:04 +0100228 Arfcn arfcn,
229 OCT2 padding2
230 } with { variant "" };
231
Harald Weltef6543322017-07-16 07:35:10 +0200232 type record L1ctlFbsbFlags {
233 BIT5 padding,
234 boolean sb,
235 boolean fb1,
236 boolean fb0
Harald Welte344c0cf2018-03-09 16:17:45 +0100237 } with { variant "FIELDORDER(msb)" };
Harald Weltef6543322017-07-16 07:35:10 +0200238
Harald Weltef8df4cb2018-03-10 15:15:08 +0100239 template (value) L1ctlFbsbFlags t_L1CTL_FBSB_F_ALL := {
Harald Welte66110f02017-07-16 21:05:18 +0200240 padding := '00000'B,
241 sb := true,
242 fb1 := true,
243 fb0 := true
244 };
245
Harald Weltef6543322017-07-16 07:35:10 +0200246 type record L1ctlFbsbReq {
247 Arfcn arfcn,
248 uint16_t timeout_tdma_frames,
249 uint16_t freq_err_thresh1,
250 uint16_t freq_err_thresh2,
251 uint8_t num_freqerr_avg,
252 L1ctlFbsbFlags flags,
253 uint8_t sync_info_idx,
254 L1ctlCcchMode ccch_mode,
255 GsmRxLev rxlev_exp
256 } with { variant "" };
257
258 type record L1ctlCcchModeReq {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100259 L1ctlCcchMode ccch_mode,
260 OCT3 padding
Harald Weltef6543322017-07-16 07:35:10 +0200261 } with { variant "" };
262
263 type record L1ctlTchModeReq {
264 L1ctlTchMode tch_mode,
265 L1ctlAudioMode audio_mode,
266 OCT2 padding
267 } with { variant "" };
268
269 type record L1ctlRachReq {
270 uint8_t ra,
271 uint8_t combined,
272 uint16_t offset
273 } with { variant "" };
274
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700275 type enumerated L1ctlRachSynchSeq {
276 RACH_SYNCH_SEQ_TS0 (0),
277 RACH_SYNCH_SEQ_TS1,
278 RACH_SYNCH_SEQ_TS2
279 } with { variant "FIELDLENGTH(8)" };
280
281 type record L1ctlExtRachReq {
282 uint16_t ra11,
283 L1ctlRachSynchSeq synch_seq,
284 uint8_t combined,
285 uint16_t offset
286 } with { variant "" };
287
Harald Weltef6543322017-07-16 07:35:10 +0200288 type record L1ctlParReq {
289 int8_t ta,
290 uint8_t tx_power,
291 OCT2 padding
292 } with { variant "" };
293
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200294 type record L1ctlDataReq {
295 SacchL1Header l1header optional,
296 octetstring l2_payload
297 } with { variant "" };
298
Vadim Yanitskiye8ea3ee2020-05-27 13:29:48 +0700299 type record length(0..64) of Arfcn L1ctlMA;
Harald Weltef6543322017-07-16 07:35:10 +0200300 type record L1ctlH1 {
301 uint8_t hsn,
302 uint8_t maio,
303 uint8_t n,
Vadim Yanitskiye8ea3ee2020-05-27 13:29:48 +0700304 OCT1 spare,
305 L1ctlMA ma,
306 octetstring padding
307 } with {
308 variant (n) "LENGTHTO(ma)"
309 variant (n) "UNIT(elements)"
310 /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=562849.
311 * TL;DR The reference point of the PADDING attribute is the beginning
312 * of the message, not the beginning of the type/field it's applied on.
313 * Therefore we cannot use it here, and have to add padding manually.
314 * variant (ma) "PADDING(128)" */
315 };
Harald Weltef6543322017-07-16 07:35:10 +0200316
317 type record L1ctlDmEstReq {
318 GsmTsc tsc,
319 uint8_t h,
320 Arfcn arfcn optional,
321 L1ctlH1 hopping optional,
322 L1ctlTchMode tch_mode,
323 L1ctlAudioMode audio_mode
324 } with { variant (arfcn) "PRESENCE(h = 0)"
325 variant (hopping) "PRESENCE(h = 1)" };
326
327 type record L1ctlReset {
328 L1ctlResetType reset_type,
329 OCT3 padding
330 } with { variant "" };
331
Harald Weltee613f962018-04-18 22:38:16 +0200332 type record L1CtlCryptoReq {
333 uint8_t algo,
334 uint8_t key_len,
335 octetstring key
336 } with { variant (key_len) "LENGTHTO(key)" };
337
Harald Weltef6543322017-07-16 07:35:10 +0200338
339 type record L1ctlTrafficReq {
Vadim Yanitskiye01691d2018-10-29 00:18:04 +0700340 octetstring data
Harald Welte7024baa2018-03-02 23:37:51 +0100341 } with {
342 variant (data) "BYTEORDER(first)"
343 }
Harald Weltef6543322017-07-16 07:35:10 +0200344
Harald Welte00d4dac2017-07-30 00:50:32 +0200345 type record length(8) of uint8_t TfiUsfArr;
346
347 type record L1ctlTbfCfgReq {
348 uint8_t tbf_nr,
349 boolean is_uplink,
350 OCT2 padding,
351 TfiUsfArr tfi_usf
352 } with { variant (is_uplink) "FIELDLENGTH(8)" };
353
Harald Weltef6543322017-07-16 07:35:10 +0200354 type union L1ctlUlPayload {
355 L1ctlFbsbReq fbsb_req,
356 L1ctlCcchModeReq ccch_mode_req,
357 L1ctlTchModeReq tch_mode_req,
358 L1ctlRachReq rach_req,
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700359 L1ctlExtRachReq ext_rach_req,
Harald Weltef6543322017-07-16 07:35:10 +0200360 L1ctlParReq par_req,
361 L1ctlDmEstReq dm_est_req,
362 L1ctlReset reset_req,
363 //L1ctlNeighPmReq neigh_pm_req,
Harald Weltee613f962018-04-18 22:38:16 +0200364 L1CtlCryptoReq crypto_req,
Harald Weltef6543322017-07-16 07:35:10 +0200365 L1ctlTrafficReq traffic_req,
Harald Welte00d4dac2017-07-30 00:50:32 +0200366 L1ctlTbfCfgReq tbf_cfg_req,
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200367 L1ctlDataReq data_req,
Harald Weltef6543322017-07-16 07:35:10 +0200368 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100369 } with {
370 variant (other) "BYTEORDER(first)"
371 };
Harald Weltef6543322017-07-16 07:35:10 +0200372
373 type record L1ctlUlMessage {
374 L1ctlHeader header,
375 L1ctlUlInfo ul_info optional,
Harald Welteb3c226e2017-07-30 17:18:01 +0200376 L1ctlUlTbfInfo ul_info_tbf optional,
Harald Welte3a40ec72018-03-02 20:45:04 +0100377 L1ctlUlAbsInfo ul_info_abs optional,
Harald Weltef6543322017-07-16 07:35:10 +0200378 L1ctlUlPayload payload
379 } with { variant (ul_info) "PRESENCE(header.msg_type = L1CTL_RACH_REQ,
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700380 header.msg_type = L1CTL_EXT_RACH_REQ,
Harald Weltef6543322017-07-16 07:35:10 +0200381 header.msg_type = L1CTL_PARAM_REQ,
382 header.msg_type = L1CTL_CRYPTO_REQ,
383 header.msg_type = L1CTL_DATA_REQ,
384 header.msg_type = L1CTL_DM_EST_REQ,
385 header.msg_type = L1CTL_DM_FREQ_REQ,
386 header.msg_type = L1CTL_DM_REL_REQ,
387 header.msg_type = L1CTL_TRAFFIC_REQ)"
Harald Welteb3c226e2017-07-30 17:18:01 +0200388 variant (ul_info_tbf) "PRESENCE(header.msg_type = L1CTL_DATA_TBF_REQ)"
Harald Welte3a40ec72018-03-02 20:45:04 +0100389 variant (ul_info_abs) "PRESENCE(header.msg_type = L1CTL_DATA_ABS_REQ)"
Harald Weltef6543322017-07-16 07:35:10 +0200390 variant (payload) "CROSSTAG(fbsb_req, header.msg_type = L1CTL_FBSB_REQ;
391 ccch_mode_req, header.msg_type = L1CTL_CCCH_MODE_REQ;
392 tch_mode_req, header.msg_type = L1CTL_TCH_MODE_REQ;
393 rach_req, header.msg_type = L1CTL_RACH_REQ;
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700394 ext_rach_req, header.msg_type = L1CTL_EXT_RACH_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200395 par_req, header.msg_type = L1CTL_PARAM_REQ;
396 dm_est_req, header.msg_type = L1CTL_DM_EST_REQ;
397 reset_req, header.msg_type = L1CTL_RESET_REQ;
Harald Weltee613f962018-04-18 22:38:16 +0200398 crypto_req, header.msg_type = L1CTL_CRYPTO_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200399 traffic_req, header.msg_type = L1CTL_TRAFFIC_REQ;
Harald Welte00d4dac2017-07-30 00:50:32 +0200400 tbf_cfg_req, header.msg_type = L1CTL_TBF_CFG_REQ;
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200401 data_req, header.msg_type = L1CTL_DATA_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200402 other, OTHERWISE;
403 )" };
404
405 external function enc_L1ctlUlMessage(in L1ctlUlMessage msg) return octetstring
406 with { extension "prototype(convert) encode(RAW)" };
407 external function dec_L1ctlUlMessage(in octetstring stream) return L1ctlUlMessage
408 with { extension "prototype(convert) decode(RAW)" };
409
Harald Welte52c713c2017-07-16 15:44:44 +0200410 type record L1ctlUlMessageLV {
411 uint16_t len,
412 L1ctlUlMessage msg
413 } with { variant (len) "LENGTHTO(msg)" };
414
415 external function enc_L1ctlUlMessageLV(in L1ctlUlMessageLV msg) return octetstring
416 with { extension "prototype(convert) encode(RAW)" };
417 external function dec_L1ctlUlMessageLV(in octetstring stream) return L1ctlUlMessageLV
418 with { extension "prototype(convert) decode(RAW)" };
419
420 type record L1ctlDlMessageLV {
421 uint16_t len,
422 L1ctlDlMessage msg
423 } with { variant (len) "LENGTHTO(msg)" };
424
425 external function enc_L1ctlDlMessageLV(in L1ctlDlMessageLV msg) return octetstring
426 with { extension "prototype(convert) encode(RAW)" };
427 external function dec_L1ctlDlMessageLV(in octetstring stream) return L1ctlDlMessageLV
428 with { extension "prototype(convert) decode(RAW)" };
429
430
Harald Welte9e4725d2017-07-16 23:18:09 +0200431
432
433 /* for generating RESET_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100434 template (value) L1ctlUlMessage t_L1ctlResetReq(L1ctlResetType rst_type) := {
435 header := ts_L1ctlHeader(L1CTL_RESET_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200436 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200437 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100438 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200439 payload := {
440 reset_req := {
441 reset_type := rst_type,
442 padding := '000000'O
443 }
444 }
445 };
446
447 /* for generating FBSB_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100448 template (value) L1ctlUlMessage ts_L1CTL_FBSB_REQ(Arfcn arfcn, L1ctlFbsbFlags flags,
449 uint8_t sync_info_idx,
450 L1ctlCcchMode ccch_mode,
451 GsmRxLev rxlev_exp) := {
452 header := ts_L1ctlHeader(L1CTL_FBSB_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200453 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200454 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100455 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200456 payload := {
457 fbsb_req := {
458 arfcn := arfcn,
Harald Weltea82f7e62018-02-22 18:51:33 +0100459 timeout_tdma_frames := 250, /* about 1s */
Harald Welte9e4725d2017-07-16 23:18:09 +0200460 freq_err_thresh1 := 10000,
461 freq_err_thresh2 := 800,
462 num_freqerr_avg := 3,
463 flags := flags,
464 sync_info_idx := sync_info_idx,
465 ccch_mode := ccch_mode,
466 rxlev_exp := rxlev_exp
467 }
468 }
469 };
470
471 /* for matching against incoming FBSB_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100472 template L1ctlDlMessage tr_L1CTL_FBSB_CONF(template uint8_t result) := {
473 header := tr_L1ctlHeader(L1CTL_FBSB_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200474 dl_info := ?,
475 payload := {
476 fbsb_conf := {
477 initial_freq_err := ?,
478 result := result,
479 bsic := ?
480 }
481 }
482 };
483
Harald Weltef8df4cb2018-03-10 15:15:08 +0100484 template (value) L1ctlUlMessage ts_L1CTL_CCCH_MODE_REQ(L1ctlCcchMode ccch_mode) := {
485 header := ts_L1ctlHeader(L1CTL_CCCH_MODE_REQ),
486 ul_info := omit,
487 ul_info_tbf := omit,
488 ul_info_abs := omit,
489 payload := {
490 ccch_mode_req := {
491 ccch_mode := ccch_mode,
492 padding := '000000'O
493 }
494 }
495 };
496
Harald Welte3757e602018-03-10 17:12:02 +0100497
498 template L1ctlDlMessage tr_L1CTL_MsgType(template L1ctlMsgType msg_type) := {
499 header := tr_L1ctlHeader(msg_type),
500 dl_info := *,
Harald Weltef56cc492018-04-15 10:58:43 +0200501 payload := *
Harald Welte3757e602018-03-10 17:12:02 +0100502 }
503
504 template L1ctlDlMessage tr_L1CTL_CCCH_MODE_CONF := tr_L1CTL_MsgType(L1CTL_CCCH_MODE_CONF);
Harald Weltef8df4cb2018-03-10 15:15:08 +0100505
Vadim Yanitskiye432ba92019-05-31 18:44:13 +0700506 template L1ctlUlMessage ts_L1CTL_RACH_REQ(uint8_t ra, uint8_t combined, uint16_t offset,
507 template (value) RslChannelNr chan_nr := ts_RslChanNr_RACH(0),
508 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0)) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100509 header := ts_L1ctlHeader(L1CTL_RACH_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200510 ul_info := {
Vadim Yanitskiye432ba92019-05-31 18:44:13 +0700511 chan_nr := chan_nr,
512 link_id := link_id,
Harald Welte9e4725d2017-07-16 23:18:09 +0200513 padding := '0000'O
514 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200515 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100516 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200517 payload := {
518 rach_req := {
519 ra := ra,
520 combined := combined,
521 offset := offset
522 }
523 }
524 }
525
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700526 template L1ctlUlMessage ts_L1CTL_EXT_RACH_REQ(
527 uint16_t ra11, L1ctlRachSynchSeq seq,
528 uint8_t combined, uint16_t offset
529 ) := {
530 header := ts_L1ctlHeader(L1CTL_EXT_RACH_REQ),
531 ul_info := {
532 /* FIXME: both RSL chan_nr and link_id should be configurable */
533 chan_nr := t_RslChanNr_RACH(0),
534 link_id := ts_RslLinkID_DCCH(0),
535 padding := '0000'O
536 },
537 ul_info_tbf := omit,
538 ul_info_abs := omit,
539 payload := {
540 ext_rach_req := {
541 ra11 := ra11,
542 synch_seq := seq,
543 combined := combined,
544 offset := offset
545 }
546 }
547 }
548
Harald Weltef8df4cb2018-03-10 15:15:08 +0100549 template L1ctlUlMessage ts_L1CTL_PAR_REQ(uint8_t ta, uint8_t tx_power) := {
550 header := ts_L1ctlHeader(L1CTL_PARAM_REQ),
Harald Welte37052732018-03-09 19:38:46 +0100551 ul_info := {
552 chan_nr := t_RslChanNr_RACH(0),
553 link_id := ts_RslLinkID_DCCH(0),
554 padding := '0000'O
555 },
556 ul_info_tbf := omit,
557 ul_info_abs := omit,
558 payload := {
559 par_req := {
560 ta := ta,
561 tx_power := tx_power,
562 padding := '0000'O
563 }
564 }
565 }
566
Vadim Yanitskiy5afe8852020-05-27 14:40:51 +0700567 /* Base template to be inherited by ts_L1CTL_DM_EST_REQ_H0 and ts_L1CTL_DM_EST_REQ_H1 */
568 private template (value) L1ctlUlMessage ts_L1CTL_DM_EST_REQ(template (value) RslChannelNr chan_nr,
569 template (value) GsmTsc tsc) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100570 header := ts_L1ctlHeader(L1CTL_DM_EST_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200571 ul_info := {
572 chan_nr := chan_nr,
573 link_id := ts_RslLinkID_DCCH(0),
574 padding := '0000'O
575 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200576 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100577 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200578 payload := {
579 dm_est_req := {
580 tsc := tsc,
Vadim Yanitskiyfe052962020-10-19 13:27:09 +0700581 tch_mode := L1CTL_CHAN_MODE_SIGN,
Harald Welte9e4725d2017-07-16 23:18:09 +0200582 audio_mode := t_L1CTL_AudioModeNone
583 }
584 }
585 }
586
Vadim Yanitskiy5afe8852020-05-27 14:40:51 +0700587 template (value) L1ctlUlMessage ts_L1CTL_DM_EST_REQ_H0(template (value) RslChannelNr chan_nr,
588 template (value) GsmTsc tsc,
589 template (value) GsmArfcn arfcn)
590 modifies ts_L1CTL_DM_EST_REQ := {
591 payload := {
592 dm_est_req := {
593 h := 0,
594 arfcn := { false, arfcn },
595 hopping := omit
596 }
597 }
598 }
599
Vadim Yanitskiyeda90812020-05-27 14:51:18 +0700600 template (value) L1ctlUlMessage ts_L1CTL_DM_EST_REQ_H1(template (value) RslChannelNr chan_nr,
601 template (value) GsmTsc tsc,
602 template (value) uint6_t hsn,
603 template (value) uint6_t maio,
604 template (value) L1ctlMA ma)
605 modifies ts_L1CTL_DM_EST_REQ := {
606 payload := {
607 dm_est_req := {
608 h := 1,
609 arfcn := omit,
610 hopping := {
611 hsn := hsn,
612 maio := maio,
613 n := sizeof(ma),
614 spare := '00'O,
615 ma := ma,
616 /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=562849 */
617 padding := f_pad_oct(''O, (64 - sizeof(ma)) * 2, '00'O)
618 }
619 }
620 }
621 }
622
Harald Weltef8df4cb2018-03-10 15:15:08 +0100623 template L1ctlUlMessage ts_L1CTL_DM_REL_REQ(RslChannelNr chan_nr) := {
624 header := ts_L1ctlHeader(L1CTL_DM_REL_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200625 ul_info := {
626 chan_nr := chan_nr,
627 link_id := ts_RslLinkID_DCCH(0),
628 padding := '0000'O
629 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200630 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100631 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200632 payload := {
633 other := ''O
634 }
635 }
636
Harald Weltef8df4cb2018-03-10 15:15:08 +0100637 template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ(template (value) RslChannelNr chan_nr,
638 template (value) RslLinkId link_id,
639 octetstring l2_data) := {
640 header := ts_L1ctlHeader(L1CTL_DATA_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200641 ul_info := {
642 chan_nr := chan_nr,
643 link_id := link_id,
644 padding := '0000'O
645 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200646 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100647 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200648 payload := {
Vadim Yanitskiy0a8d6da2019-05-28 22:18:28 +0700649 data_req := {
650 l1header := omit,
651 l2_payload := l2_data
652 }
Harald Welte9e4725d2017-07-16 23:18:09 +0200653 }
654 }
655
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200656 template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ_SACCH(template (value) RslChannelNr chan_nr,
657 template (value) RslLinkId link_id,
Vadim Yanitskiy0a8d6da2019-05-28 22:18:28 +0700658 template (value) SacchL1Header l1h,
659 octetstring l2_data) := {
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200660 header := ts_L1ctlHeader(L1CTL_DATA_REQ),
661 ul_info := {
662 chan_nr := chan_nr,
663 link_id := link_id,
664 padding := '0000'O
665 },
666 ul_info_tbf := omit,
667 ul_info_abs := omit,
668 payload := {
Vadim Yanitskiy0a8d6da2019-05-28 22:18:28 +0700669 data_req := {
670 l1header := l1h,
671 l2_payload := l2_data
672 }
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200673 }
674 }
675
Vadim Yanitskiyf3cc6492019-06-30 16:34:30 +0700676 template (value) L1ctlUlMessage ts_L1CTL_TRAFFIC_REQ(template (value) RslChannelNr chan_nr,
677 template (value) RslLinkId link_id,
678 octetstring frame) := {
679 header := ts_L1ctlHeader(L1CTL_TRAFFIC_REQ),
680 ul_info := {
681 chan_nr := chan_nr,
682 link_id := link_id,
683 padding := '0000'O
684 },
685 ul_info_tbf := omit,
686 ul_info_abs := omit,
687 payload := {
688 traffic_req := {
689 data := frame
690 }
691 }
692 };
693
Harald Weltef8df4cb2018-03-10 15:15:08 +0100694 template (value) L1ctlUlMessage ts_L1CTL_TBF_CFG_REQ(boolean is_uplink, TfiUsfArr tfi_usf) := {
695 header := ts_L1ctlHeader(L1CTL_TBF_CFG_REQ),
Harald Welte00d4dac2017-07-30 00:50:32 +0200696 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200697 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100698 ul_info_abs := omit,
Harald Welte00d4dac2017-07-30 00:50:32 +0200699 payload := {
700 tbf_cfg_req := {
701 tbf_nr := 0,
702 is_uplink := is_uplink,
703 padding := '0000'O,
704 tfi_usf := tfi_usf
705 }
706 }
707 };
708
Harald Weltef8df4cb2018-03-10 15:15:08 +0100709 template L1ctlDlMessage tr_L1CTL_TBF_CFG_CONF(template boolean is_uplink) := {
710 header := tr_L1ctlHeader(L1CTL_TBF_CFG_CONF),
Harald Welte00d4dac2017-07-30 00:50:32 +0200711 dl_info := omit,
712 payload := {
713 tbf_cfg_conf := {
714 tbf_nr := 0,
715 is_uplink := is_uplink,
716 padding := ?,
717 tfi_usf := ?
718 }
719 }
720 };
721
Harald Weltef8df4cb2018-03-10 15:15:08 +0100722 template (value) L1ctlUlMessage ts_L1CTL_DATA_TBF_REQ(octetstring l2_data,
723 L1ctlGprsCs cs := L1CTL_CS1,
724 uint8_t tbf_nr := 0) := {
725 header := ts_L1ctlHeader(L1CTL_DATA_TBF_REQ),
Harald Welteb3c226e2017-07-30 17:18:01 +0200726 ul_info := omit,
727 ul_info_tbf := {
728 tbf_nr := tbf_nr,
Harald Welte1dcc3712017-08-01 00:05:52 +0200729 cs := cs,
730 padding := '0000'O
Harald Welteb3c226e2017-07-30 17:18:01 +0200731 },
Harald Welte3a40ec72018-03-02 20:45:04 +0100732 ul_info_abs := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200733 payload := {
734 other := l2_data
735 }
736 }
737
Harald Weltef8df4cb2018-03-10 15:15:08 +0100738 template (value) L1ctlUlMessage ts_L1CTL_DATA_ABS_REQ(octetstring l2_data, Arfcn arfcn,
Harald Welte3a40ec72018-03-02 20:45:04 +0100739 uint8_t ts, GsmFrameNumber fn,
740 L1ctlGprsCs cs := L1CTL_CS1,
741 uint8_t tbf_nr := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100742 header := ts_L1ctlHeader(L1CTL_DATA_ABS_REQ),
Harald Welte3a40ec72018-03-02 20:45:04 +0100743 ul_info := omit,
744 ul_info_tbf := omit,
745 ul_info_abs := {
746 tbf_nr := tbf_nr,
747 cs := cs,
748 ts_nr := ts,
749 padding := '00'O,
750 fn := fn,
751 arfcn := arfcn,
752 padding2 := '0000'O
753 },
754 payload := {
755 other := l2_data
756 }
757 }
758
759
Harald Welte9e4725d2017-07-16 23:18:09 +0200760 /* for matching against incoming RACH_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100761 template L1ctlDlMessage tr_L1CTL_RACH_CONF := {
762 header := tr_L1ctlHeader(L1CTL_RACH_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200763 dl_info := ?,
Harald Weltef56cc492018-04-15 10:58:43 +0200764 payload := *
Harald Welte9e4725d2017-07-16 23:18:09 +0200765 };
766
Harald Weltece6dc442018-02-21 22:00:21 +0100767 /* for matching against incoming DATA_IND */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100768 template L1ctlDlMessage tr_L1CTL_DATA_IND(template RslChannelNr chan_nr,
Harald Welte68e495b2018-02-25 00:05:57 +0100769 template RslLinkId link_id := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100770 template octetstring l2_data := ?,
771 template uint8_t num_biterr := 0,
772 template uint8_t fire_crc := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100773 header := tr_L1ctlHeader(L1CTL_DATA_IND),
Harald Welte9e4725d2017-07-16 23:18:09 +0200774 dl_info := {
775 chan_nr := chan_nr,
Harald Weltece6dc442018-02-21 22:00:21 +0100776 link_id := link_id,
Harald Welte9e4725d2017-07-16 23:18:09 +0200777 arfcn := ?,
778 frame_nr := ?,
779 rx_level := ?,
780 snr := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100781 num_biterr := num_biterr,
782 fire_crc := fire_crc
Harald Welte9e4725d2017-07-16 23:18:09 +0200783 },
784 payload := {
Harald Welte68e495b2018-02-25 00:05:57 +0100785 data_ind := {
786 payload := l2_data
787 }
Harald Welte9e4725d2017-07-16 23:18:09 +0200788 }
789 };
790
Vadim Yanitskiyf3cc6492019-06-30 16:34:30 +0700791 /* for matching against incoming TRAFFIC_IND */
792 template L1ctlDlMessage tr_L1CTL_TRAFFIC_IND(template RslChannelNr chan_nr,
793 template RslLinkId link_id := ?,
794 template octetstring frame := ?,
795 template uint8_t num_biterr := 0,
796 template uint8_t fire_crc := 0) := {
797 header := tr_L1ctlHeader(L1CTL_TRAFFIC_IND),
798 dl_info := {
799 chan_nr := chan_nr,
800 link_id := link_id,
801 arfcn := ?,
802 frame_nr := ?,
803 rx_level := ?,
804 snr := ?,
805 num_biterr := num_biterr,
806 fire_crc := fire_crc
807 },
808 payload := {
809 traffic_ind := {
810 data := frame
811 }
812 }
813 };
814
Harald Weltee613f962018-04-18 22:38:16 +0200815 template (value) L1ctlUlMessage ts_L1CTL_CRYPTO_REQ(RslChannelNr chan_nr, uint8_t algo,
816 octetstring key) := {
817 header := ts_L1ctlHeader(L1CTL_CRYPTO_REQ),
818 ul_info := {
819 chan_nr := chan_nr,
820 link_id := ts_RslLinkID_DCCH(0),
821 padding := '0000'O
822 },
823 ul_info_tbf := omit,
824 ul_info_abs := omit,
825 payload := {
826 crypto_req := {
827 algo := algo,
828 key_len := 0, /* overwritten */
829 key := key
830 }
831 }
832 };
833
Harald Welte68e495b2018-02-25 00:05:57 +0100834 const octetstring c_DummyUI := '0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O;
835
Harald Welte7024baa2018-03-02 23:37:51 +0100836/* We use "BYTEORDER(last)" so we get little-endian integers. Unfortuantely, this also
837 switches the byte ordering in octet strings, so we need to explicitly annotate them :/ */
Harald Weltef6543322017-07-16 07:35:10 +0200838} with { encode "RAW" };