blob: c5b10e4be0fe48e3e994ea010f2f2bba02460ffd [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
Vadim Yanitskiy7ce605f2020-10-19 16:04:38 +0700151 type enumerated L1ctlLoopMode {
152 L1CTL_LOOP_MODE_OPEN ('00000000'B),
153 L1CTL_LOOP_MODE_A ('00000001'B),
154 L1CTL_LOOP_MODE_B ('00000010'B),
155 L1CTL_LOOP_MODE_C ('00000011'B),
156 L1CTL_LOOP_MODE_D ('00000100'B),
157 L1CTL_LOOP_MODE_E ('00000101'B),
158 L1CTL_LOOP_MODE_F ('00000110'B),
159 L1CTL_LOOP_MODE_I ('00000111'B)
160 } with { variant "FIELDLENGTH(8)" };
161
Harald Weltef6543322017-07-16 07:35:10 +0200162 type record L1ctlAudioMode {
163 BIT4 padding,
164 boolean tx_microphone,
165 boolean tx_traffic_req,
166 boolean rx_speaker,
167 boolean rx_traffic_ind
168 } with { variant "" };
169
Harald Weltef8df4cb2018-03-10 15:15:08 +0100170 template (value) L1ctlAudioMode t_L1CTL_AudioModeNone := { '0000'B, false, false, false, false };
Harald Welte66110f02017-07-16 21:05:18 +0200171
Harald Weltef6543322017-07-16 07:35:10 +0200172 type record L1ctlTchModeConf {
173 L1ctlTchMode tch_mode,
174 L1ctlAudioMode audio_mode,
175 OCT2 padding
176 } with { variant "" };
177
178 type record L1ctlDataInd {
Vadim Yanitskiy2a92e2a2019-05-28 21:13:35 +0700179 octetstring payload
Harald Welte7024baa2018-03-02 23:37:51 +0100180 } with {
181 variant (payload) "BYTEORDER(first)"
182 };
Harald Weltef6543322017-07-16 07:35:10 +0200183
184 type union L1ctlDlPayload {
185 L1ctlFbsbConf fbsb_conf,
186 L1ctlCcchModeConf ccch_mode_conf,
187 L1ctlTchModeConf tch_mode_conf,
188 L1ctlDataInd data_ind,
189 L1ctlTrafficReq traffic_ind,
Harald Welte00d4dac2017-07-30 00:50:32 +0200190 L1ctlTbfCfgReq tbf_cfg_conf,
Harald Weltef6543322017-07-16 07:35:10 +0200191 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100192 } with {
193 variant (other) "BYTEORDER(first)"
194 };
Harald Weltef6543322017-07-16 07:35:10 +0200195
196 type record L1ctlDlMessage {
197 L1ctlHeader header,
198 L1ctlDlInfo dl_info optional,
Harald Weltef56cc492018-04-15 10:58:43 +0200199 L1ctlDlPayload payload optional
Harald Weltef6543322017-07-16 07:35:10 +0200200 } with { variant (dl_info) "PRESENCE(header.msg_type = L1CTL_FBSB_CONF,
201 header.msg_type = L1CTL_RACH_CONF,
202 header.msg_type = L1CTL_DATA_IND,
203 header.msg_type = L1CTL_DATA_CONF,
Harald Welte3c4cbf62018-03-30 10:31:39 +0200204 header.msg_type = L1CTL_TRAFFIC_IND,
205 header.msg_type = L1CTL_TRAFFIC_CONF)"
Harald Weltef6543322017-07-16 07:35:10 +0200206 variant (payload) "CROSSTAG(fbsb_conf, header.msg_type = L1CTL_FBSB_CONF;
207 ccch_mode_conf, header.msg_type = L1CTL_CCCH_MODE_CONF;
208 tch_mode_conf, header.msg_type = L1CTL_TCH_MODE_CONF;
209 data_ind, header.msg_type = L1CTL_DATA_IND;
210 traffic_ind, header.msg_type = L1CTL_TRAFFIC_IND;
Harald Welte00d4dac2017-07-30 00:50:32 +0200211 tbf_cfg_conf, header.msg_type = L1CTL_TBF_CFG_CONF;
Harald Weltef6543322017-07-16 07:35:10 +0200212 other, OTHERWISE;
213 )" };
214
215 external function enc_L1ctlDlMessage(in L1ctlDlMessage msg) return octetstring
216 with { extension "prototype(convert) encode(RAW)" };
217 external function dec_L1ctlDlMessage(in octetstring stream) return L1ctlDlMessage
218 with { extension "prototype(convert) decode(RAW)" };
219
220
221 type record L1ctlUlInfo {
Harald Welte8e4db2c2017-07-16 18:54:55 +0200222 RslChannelNr chan_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200223 RslLinkId link_id,
224 OCT2 padding
225 } with { variant "" };
226
Harald Welteb3c226e2017-07-30 17:18:01 +0200227 type record L1ctlUlTbfInfo {
228 uint8_t tbf_nr,
Harald Welte1dcc3712017-08-01 00:05:52 +0200229 L1ctlGprsCs cs,
230 OCT2 padding
Harald Welteb3c226e2017-07-30 17:18:01 +0200231 } with { variant "" };
232
Harald Welte3a40ec72018-03-02 20:45:04 +0100233 type record L1ctlUlAbsInfo {
234 uint8_t tbf_nr,
235 L1ctlGprsCs cs,
236 uint8_t ts_nr,
237 OCT1 padding,
Harald Welte7024baa2018-03-02 23:37:51 +0100238 uint32_le fn,
Harald Welte3a40ec72018-03-02 20:45:04 +0100239 Arfcn arfcn,
240 OCT2 padding2
241 } with { variant "" };
242
Harald Weltef6543322017-07-16 07:35:10 +0200243 type record L1ctlFbsbFlags {
244 BIT5 padding,
245 boolean sb,
246 boolean fb1,
247 boolean fb0
Harald Welte344c0cf2018-03-09 16:17:45 +0100248 } with { variant "FIELDORDER(msb)" };
Harald Weltef6543322017-07-16 07:35:10 +0200249
Harald Weltef8df4cb2018-03-10 15:15:08 +0100250 template (value) L1ctlFbsbFlags t_L1CTL_FBSB_F_ALL := {
Harald Welte66110f02017-07-16 21:05:18 +0200251 padding := '00000'B,
252 sb := true,
253 fb1 := true,
254 fb0 := true
255 };
256
Harald Weltef6543322017-07-16 07:35:10 +0200257 type record L1ctlFbsbReq {
258 Arfcn arfcn,
259 uint16_t timeout_tdma_frames,
260 uint16_t freq_err_thresh1,
261 uint16_t freq_err_thresh2,
262 uint8_t num_freqerr_avg,
263 L1ctlFbsbFlags flags,
264 uint8_t sync_info_idx,
265 L1ctlCcchMode ccch_mode,
266 GsmRxLev rxlev_exp
267 } with { variant "" };
268
269 type record L1ctlCcchModeReq {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100270 L1ctlCcchMode ccch_mode,
271 OCT3 padding
Harald Weltef6543322017-07-16 07:35:10 +0200272 } with { variant "" };
273
274 type record L1ctlTchModeReq {
275 L1ctlTchMode tch_mode,
276 L1ctlAudioMode audio_mode,
Vadim Yanitskiy7ce605f2020-10-19 16:04:38 +0700277 L1ctlLoopMode loop_mode,
278 OCT1 padding
Harald Weltef6543322017-07-16 07:35:10 +0200279 } with { variant "" };
280
281 type record L1ctlRachReq {
282 uint8_t ra,
283 uint8_t combined,
284 uint16_t offset
285 } with { variant "" };
286
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700287 type enumerated L1ctlRachSynchSeq {
288 RACH_SYNCH_SEQ_TS0 (0),
289 RACH_SYNCH_SEQ_TS1,
290 RACH_SYNCH_SEQ_TS2
291 } with { variant "FIELDLENGTH(8)" };
292
293 type record L1ctlExtRachReq {
294 uint16_t ra11,
295 L1ctlRachSynchSeq synch_seq,
296 uint8_t combined,
297 uint16_t offset
298 } with { variant "" };
299
Harald Weltef6543322017-07-16 07:35:10 +0200300 type record L1ctlParReq {
301 int8_t ta,
302 uint8_t tx_power,
303 OCT2 padding
304 } with { variant "" };
305
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200306 type record L1ctlDataReq {
307 SacchL1Header l1header optional,
308 octetstring l2_payload
309 } with { variant "" };
310
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700311 type record L1ctlH0 {
312 uint8_t h,
313 Arfcn arfcn,
314 octetstring padding length(130)
315 } with { variant "" };
316
Vadim Yanitskiye8ea3ee2020-05-27 13:29:48 +0700317 type record length(0..64) of Arfcn L1ctlMA;
Harald Weltef6543322017-07-16 07:35:10 +0200318 type record L1ctlH1 {
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700319 uint8_t h,
Harald Weltef6543322017-07-16 07:35:10 +0200320 uint8_t hsn,
321 uint8_t maio,
322 uint8_t n,
Vadim Yanitskiye8ea3ee2020-05-27 13:29:48 +0700323 OCT1 spare,
324 L1ctlMA ma,
325 octetstring padding
326 } with {
327 variant (n) "LENGTHTO(ma)"
328 variant (n) "UNIT(elements)"
329 /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=562849.
330 * TL;DR The reference point of the PADDING attribute is the beginning
331 * of the message, not the beginning of the type/field it's applied on.
332 * Therefore we cannot use it here, and have to add padding manually.
333 * variant (ma) "PADDING(128)" */
334 };
Harald Weltef6543322017-07-16 07:35:10 +0200335
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700336 type union L1ctlH0H1 {
337 L1ctlH0 h0,
338 L1ctlH1 h1
339 } with { variant "TAG(h0, h = 0; h1, h = 1)" };
340
Harald Weltef6543322017-07-16 07:35:10 +0200341 type record L1ctlDmEstReq {
342 GsmTsc tsc,
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700343 L1ctlH0H1 h0h1,
Harald Weltef6543322017-07-16 07:35:10 +0200344 L1ctlTchMode tch_mode,
345 L1ctlAudioMode audio_mode
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700346 } with { variant "" };
Harald Weltef6543322017-07-16 07:35:10 +0200347
348 type record L1ctlReset {
349 L1ctlResetType reset_type,
350 OCT3 padding
351 } with { variant "" };
352
Harald Weltee613f962018-04-18 22:38:16 +0200353 type record L1CtlCryptoReq {
354 uint8_t algo,
355 uint8_t key_len,
356 octetstring key
357 } with { variant (key_len) "LENGTHTO(key)" };
358
Harald Weltef6543322017-07-16 07:35:10 +0200359
360 type record L1ctlTrafficReq {
Vadim Yanitskiye01691d2018-10-29 00:18:04 +0700361 octetstring data
Harald Welte7024baa2018-03-02 23:37:51 +0100362 } with {
363 variant (data) "BYTEORDER(first)"
364 }
Harald Weltef6543322017-07-16 07:35:10 +0200365
Harald Welte00d4dac2017-07-30 00:50:32 +0200366 type record length(8) of uint8_t TfiUsfArr;
367
368 type record L1ctlTbfCfgReq {
369 uint8_t tbf_nr,
370 boolean is_uplink,
371 OCT2 padding,
372 TfiUsfArr tfi_usf
373 } with { variant (is_uplink) "FIELDLENGTH(8)" };
374
Harald Weltef6543322017-07-16 07:35:10 +0200375 type union L1ctlUlPayload {
376 L1ctlFbsbReq fbsb_req,
377 L1ctlCcchModeReq ccch_mode_req,
378 L1ctlTchModeReq tch_mode_req,
379 L1ctlRachReq rach_req,
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700380 L1ctlExtRachReq ext_rach_req,
Harald Weltef6543322017-07-16 07:35:10 +0200381 L1ctlParReq par_req,
382 L1ctlDmEstReq dm_est_req,
383 L1ctlReset reset_req,
384 //L1ctlNeighPmReq neigh_pm_req,
Harald Weltee613f962018-04-18 22:38:16 +0200385 L1CtlCryptoReq crypto_req,
Harald Weltef6543322017-07-16 07:35:10 +0200386 L1ctlTrafficReq traffic_req,
Harald Welte00d4dac2017-07-30 00:50:32 +0200387 L1ctlTbfCfgReq tbf_cfg_req,
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200388 L1ctlDataReq data_req,
Harald Weltef6543322017-07-16 07:35:10 +0200389 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100390 } with {
391 variant (other) "BYTEORDER(first)"
392 };
Harald Weltef6543322017-07-16 07:35:10 +0200393
394 type record L1ctlUlMessage {
395 L1ctlHeader header,
396 L1ctlUlInfo ul_info optional,
Harald Welteb3c226e2017-07-30 17:18:01 +0200397 L1ctlUlTbfInfo ul_info_tbf optional,
Harald Welte3a40ec72018-03-02 20:45:04 +0100398 L1ctlUlAbsInfo ul_info_abs optional,
Harald Weltef6543322017-07-16 07:35:10 +0200399 L1ctlUlPayload payload
400 } with { variant (ul_info) "PRESENCE(header.msg_type = L1CTL_RACH_REQ,
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700401 header.msg_type = L1CTL_EXT_RACH_REQ,
Harald Weltef6543322017-07-16 07:35:10 +0200402 header.msg_type = L1CTL_PARAM_REQ,
403 header.msg_type = L1CTL_CRYPTO_REQ,
404 header.msg_type = L1CTL_DATA_REQ,
405 header.msg_type = L1CTL_DM_EST_REQ,
406 header.msg_type = L1CTL_DM_FREQ_REQ,
407 header.msg_type = L1CTL_DM_REL_REQ,
408 header.msg_type = L1CTL_TRAFFIC_REQ)"
Harald Welteb3c226e2017-07-30 17:18:01 +0200409 variant (ul_info_tbf) "PRESENCE(header.msg_type = L1CTL_DATA_TBF_REQ)"
Harald Welte3a40ec72018-03-02 20:45:04 +0100410 variant (ul_info_abs) "PRESENCE(header.msg_type = L1CTL_DATA_ABS_REQ)"
Harald Weltef6543322017-07-16 07:35:10 +0200411 variant (payload) "CROSSTAG(fbsb_req, header.msg_type = L1CTL_FBSB_REQ;
412 ccch_mode_req, header.msg_type = L1CTL_CCCH_MODE_REQ;
413 tch_mode_req, header.msg_type = L1CTL_TCH_MODE_REQ;
414 rach_req, header.msg_type = L1CTL_RACH_REQ;
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700415 ext_rach_req, header.msg_type = L1CTL_EXT_RACH_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200416 par_req, header.msg_type = L1CTL_PARAM_REQ;
417 dm_est_req, header.msg_type = L1CTL_DM_EST_REQ;
418 reset_req, header.msg_type = L1CTL_RESET_REQ;
Harald Weltee613f962018-04-18 22:38:16 +0200419 crypto_req, header.msg_type = L1CTL_CRYPTO_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200420 traffic_req, header.msg_type = L1CTL_TRAFFIC_REQ;
Harald Welte00d4dac2017-07-30 00:50:32 +0200421 tbf_cfg_req, header.msg_type = L1CTL_TBF_CFG_REQ;
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200422 data_req, header.msg_type = L1CTL_DATA_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200423 other, OTHERWISE;
424 )" };
425
426 external function enc_L1ctlUlMessage(in L1ctlUlMessage msg) return octetstring
427 with { extension "prototype(convert) encode(RAW)" };
428 external function dec_L1ctlUlMessage(in octetstring stream) return L1ctlUlMessage
429 with { extension "prototype(convert) decode(RAW)" };
430
Harald Welte52c713c2017-07-16 15:44:44 +0200431 type record L1ctlUlMessageLV {
432 uint16_t len,
433 L1ctlUlMessage msg
434 } with { variant (len) "LENGTHTO(msg)" };
435
436 external function enc_L1ctlUlMessageLV(in L1ctlUlMessageLV msg) return octetstring
437 with { extension "prototype(convert) encode(RAW)" };
438 external function dec_L1ctlUlMessageLV(in octetstring stream) return L1ctlUlMessageLV
439 with { extension "prototype(convert) decode(RAW)" };
440
441 type record L1ctlDlMessageLV {
442 uint16_t len,
443 L1ctlDlMessage msg
444 } with { variant (len) "LENGTHTO(msg)" };
445
446 external function enc_L1ctlDlMessageLV(in L1ctlDlMessageLV msg) return octetstring
447 with { extension "prototype(convert) encode(RAW)" };
448 external function dec_L1ctlDlMessageLV(in octetstring stream) return L1ctlDlMessageLV
449 with { extension "prototype(convert) decode(RAW)" };
450
451
Harald Welte9e4725d2017-07-16 23:18:09 +0200452
453
454 /* for generating RESET_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100455 template (value) L1ctlUlMessage t_L1ctlResetReq(L1ctlResetType rst_type) := {
456 header := ts_L1ctlHeader(L1CTL_RESET_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200457 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200458 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100459 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200460 payload := {
461 reset_req := {
462 reset_type := rst_type,
463 padding := '000000'O
464 }
465 }
466 };
467
468 /* for generating FBSB_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100469 template (value) L1ctlUlMessage ts_L1CTL_FBSB_REQ(Arfcn arfcn, L1ctlFbsbFlags flags,
470 uint8_t sync_info_idx,
471 L1ctlCcchMode ccch_mode,
472 GsmRxLev rxlev_exp) := {
473 header := ts_L1ctlHeader(L1CTL_FBSB_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200474 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200475 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100476 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200477 payload := {
478 fbsb_req := {
479 arfcn := arfcn,
Harald Weltea82f7e62018-02-22 18:51:33 +0100480 timeout_tdma_frames := 250, /* about 1s */
Harald Welte9e4725d2017-07-16 23:18:09 +0200481 freq_err_thresh1 := 10000,
482 freq_err_thresh2 := 800,
483 num_freqerr_avg := 3,
484 flags := flags,
485 sync_info_idx := sync_info_idx,
486 ccch_mode := ccch_mode,
487 rxlev_exp := rxlev_exp
488 }
489 }
490 };
491
492 /* for matching against incoming FBSB_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100493 template L1ctlDlMessage tr_L1CTL_FBSB_CONF(template uint8_t result) := {
494 header := tr_L1ctlHeader(L1CTL_FBSB_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200495 dl_info := ?,
496 payload := {
497 fbsb_conf := {
498 initial_freq_err := ?,
499 result := result,
500 bsic := ?
501 }
502 }
503 };
504
Harald Weltef8df4cb2018-03-10 15:15:08 +0100505 template (value) L1ctlUlMessage ts_L1CTL_CCCH_MODE_REQ(L1ctlCcchMode ccch_mode) := {
506 header := ts_L1ctlHeader(L1CTL_CCCH_MODE_REQ),
507 ul_info := omit,
508 ul_info_tbf := omit,
509 ul_info_abs := omit,
510 payload := {
511 ccch_mode_req := {
512 ccch_mode := ccch_mode,
513 padding := '000000'O
514 }
515 }
516 };
517
Harald Welte3757e602018-03-10 17:12:02 +0100518
519 template L1ctlDlMessage tr_L1CTL_MsgType(template L1ctlMsgType msg_type) := {
520 header := tr_L1ctlHeader(msg_type),
521 dl_info := *,
Harald Weltef56cc492018-04-15 10:58:43 +0200522 payload := *
Harald Welte3757e602018-03-10 17:12:02 +0100523 }
524
525 template L1ctlDlMessage tr_L1CTL_CCCH_MODE_CONF := tr_L1CTL_MsgType(L1CTL_CCCH_MODE_CONF);
Harald Weltef8df4cb2018-03-10 15:15:08 +0100526
Vadim Yanitskiye432ba92019-05-31 18:44:13 +0700527 template L1ctlUlMessage ts_L1CTL_RACH_REQ(uint8_t ra, uint8_t combined, uint16_t offset,
528 template (value) RslChannelNr chan_nr := ts_RslChanNr_RACH(0),
529 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0)) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100530 header := ts_L1ctlHeader(L1CTL_RACH_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200531 ul_info := {
Vadim Yanitskiye432ba92019-05-31 18:44:13 +0700532 chan_nr := chan_nr,
533 link_id := link_id,
Harald Welte9e4725d2017-07-16 23:18:09 +0200534 padding := '0000'O
535 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200536 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100537 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200538 payload := {
539 rach_req := {
540 ra := ra,
541 combined := combined,
542 offset := offset
543 }
544 }
545 }
546
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700547 template L1ctlUlMessage ts_L1CTL_EXT_RACH_REQ(
548 uint16_t ra11, L1ctlRachSynchSeq seq,
549 uint8_t combined, uint16_t offset
550 ) := {
551 header := ts_L1ctlHeader(L1CTL_EXT_RACH_REQ),
552 ul_info := {
553 /* FIXME: both RSL chan_nr and link_id should be configurable */
554 chan_nr := t_RslChanNr_RACH(0),
555 link_id := ts_RslLinkID_DCCH(0),
556 padding := '0000'O
557 },
558 ul_info_tbf := omit,
559 ul_info_abs := omit,
560 payload := {
561 ext_rach_req := {
562 ra11 := ra11,
563 synch_seq := seq,
564 combined := combined,
565 offset := offset
566 }
567 }
568 }
569
Harald Weltef8df4cb2018-03-10 15:15:08 +0100570 template L1ctlUlMessage ts_L1CTL_PAR_REQ(uint8_t ta, uint8_t tx_power) := {
571 header := ts_L1ctlHeader(L1CTL_PARAM_REQ),
Harald Welte37052732018-03-09 19:38:46 +0100572 ul_info := {
573 chan_nr := t_RslChanNr_RACH(0),
574 link_id := ts_RslLinkID_DCCH(0),
575 padding := '0000'O
576 },
577 ul_info_tbf := omit,
578 ul_info_abs := omit,
579 payload := {
580 par_req := {
581 ta := ta,
582 tx_power := tx_power,
583 padding := '0000'O
584 }
585 }
586 }
587
Vadim Yanitskiy5afe8852020-05-27 14:40:51 +0700588 /* Base template to be inherited by ts_L1CTL_DM_EST_REQ_H0 and ts_L1CTL_DM_EST_REQ_H1 */
589 private template (value) L1ctlUlMessage ts_L1CTL_DM_EST_REQ(template (value) RslChannelNr chan_nr,
590 template (value) GsmTsc tsc) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100591 header := ts_L1ctlHeader(L1CTL_DM_EST_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200592 ul_info := {
593 chan_nr := chan_nr,
594 link_id := ts_RslLinkID_DCCH(0),
595 padding := '0000'O
596 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200597 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100598 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200599 payload := {
600 dm_est_req := {
601 tsc := tsc,
Vadim Yanitskiyfe052962020-10-19 13:27:09 +0700602 tch_mode := L1CTL_CHAN_MODE_SIGN,
Harald Welte9e4725d2017-07-16 23:18:09 +0200603 audio_mode := t_L1CTL_AudioModeNone
604 }
605 }
606 }
607
Vadim Yanitskiy5afe8852020-05-27 14:40:51 +0700608 template (value) L1ctlUlMessage ts_L1CTL_DM_EST_REQ_H0(template (value) RslChannelNr chan_nr,
609 template (value) GsmTsc tsc,
610 template (value) GsmArfcn arfcn)
611 modifies ts_L1CTL_DM_EST_REQ := {
612 payload := {
613 dm_est_req := {
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700614 h0h1 := {
615 h0 := {
616 h := 0,
617 arfcn := { false, arfcn },
618 padding := f_pad_oct(''O, 130, '00'O)
619 }
620 }
Vadim Yanitskiy5afe8852020-05-27 14:40:51 +0700621 }
622 }
623 }
624
Vadim Yanitskiyeda90812020-05-27 14:51:18 +0700625 template (value) L1ctlUlMessage ts_L1CTL_DM_EST_REQ_H1(template (value) RslChannelNr chan_nr,
626 template (value) GsmTsc tsc,
627 template (value) uint6_t hsn,
628 template (value) uint6_t maio,
629 template (value) L1ctlMA ma)
630 modifies ts_L1CTL_DM_EST_REQ := {
631 payload := {
632 dm_est_req := {
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700633 h0h1 := {
634 h1 := {
635 h := 1,
636 hsn := hsn,
637 maio := maio,
638 n := sizeof(ma),
639 spare := '00'O,
640 ma := ma,
641 /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=562849 */
642 padding := f_pad_oct(''O, (64 - sizeof(ma)) * 2, '00'O)
643 }
Vadim Yanitskiyeda90812020-05-27 14:51:18 +0700644 }
645 }
646 }
647 }
648
Harald Weltef8df4cb2018-03-10 15:15:08 +0100649 template L1ctlUlMessage ts_L1CTL_DM_REL_REQ(RslChannelNr chan_nr) := {
650 header := ts_L1ctlHeader(L1CTL_DM_REL_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200651 ul_info := {
652 chan_nr := chan_nr,
653 link_id := ts_RslLinkID_DCCH(0),
654 padding := '0000'O
655 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200656 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100657 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200658 payload := {
659 other := ''O
660 }
661 }
662
Harald Weltef8df4cb2018-03-10 15:15:08 +0100663 template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ(template (value) RslChannelNr chan_nr,
664 template (value) RslLinkId link_id,
665 octetstring l2_data) := {
666 header := ts_L1ctlHeader(L1CTL_DATA_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200667 ul_info := {
668 chan_nr := chan_nr,
669 link_id := link_id,
670 padding := '0000'O
671 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200672 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100673 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200674 payload := {
Vadim Yanitskiy0a8d6da2019-05-28 22:18:28 +0700675 data_req := {
676 l1header := omit,
677 l2_payload := l2_data
678 }
Harald Welte9e4725d2017-07-16 23:18:09 +0200679 }
680 }
681
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200682 template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ_SACCH(template (value) RslChannelNr chan_nr,
683 template (value) RslLinkId link_id,
Vadim Yanitskiy0a8d6da2019-05-28 22:18:28 +0700684 template (value) SacchL1Header l1h,
685 octetstring l2_data) := {
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200686 header := ts_L1ctlHeader(L1CTL_DATA_REQ),
687 ul_info := {
688 chan_nr := chan_nr,
689 link_id := link_id,
690 padding := '0000'O
691 },
692 ul_info_tbf := omit,
693 ul_info_abs := omit,
694 payload := {
Vadim Yanitskiy0a8d6da2019-05-28 22:18:28 +0700695 data_req := {
696 l1header := l1h,
697 l2_payload := l2_data
698 }
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200699 }
700 }
701
Vadim Yanitskiyf3cc6492019-06-30 16:34:30 +0700702 template (value) L1ctlUlMessage ts_L1CTL_TRAFFIC_REQ(template (value) RslChannelNr chan_nr,
703 template (value) RslLinkId link_id,
704 octetstring frame) := {
705 header := ts_L1ctlHeader(L1CTL_TRAFFIC_REQ),
706 ul_info := {
707 chan_nr := chan_nr,
708 link_id := link_id,
709 padding := '0000'O
710 },
711 ul_info_tbf := omit,
712 ul_info_abs := omit,
713 payload := {
714 traffic_req := {
715 data := frame
716 }
717 }
718 };
719
Harald Weltef8df4cb2018-03-10 15:15:08 +0100720 template (value) L1ctlUlMessage ts_L1CTL_TBF_CFG_REQ(boolean is_uplink, TfiUsfArr tfi_usf) := {
721 header := ts_L1ctlHeader(L1CTL_TBF_CFG_REQ),
Harald Welte00d4dac2017-07-30 00:50:32 +0200722 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200723 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100724 ul_info_abs := omit,
Harald Welte00d4dac2017-07-30 00:50:32 +0200725 payload := {
726 tbf_cfg_req := {
727 tbf_nr := 0,
728 is_uplink := is_uplink,
729 padding := '0000'O,
730 tfi_usf := tfi_usf
731 }
732 }
733 };
734
Harald Weltef8df4cb2018-03-10 15:15:08 +0100735 template L1ctlDlMessage tr_L1CTL_TBF_CFG_CONF(template boolean is_uplink) := {
736 header := tr_L1ctlHeader(L1CTL_TBF_CFG_CONF),
Harald Welte00d4dac2017-07-30 00:50:32 +0200737 dl_info := omit,
738 payload := {
739 tbf_cfg_conf := {
740 tbf_nr := 0,
741 is_uplink := is_uplink,
742 padding := ?,
743 tfi_usf := ?
744 }
745 }
746 };
747
Harald Weltef8df4cb2018-03-10 15:15:08 +0100748 template (value) L1ctlUlMessage ts_L1CTL_DATA_TBF_REQ(octetstring l2_data,
749 L1ctlGprsCs cs := L1CTL_CS1,
750 uint8_t tbf_nr := 0) := {
751 header := ts_L1ctlHeader(L1CTL_DATA_TBF_REQ),
Harald Welteb3c226e2017-07-30 17:18:01 +0200752 ul_info := omit,
753 ul_info_tbf := {
754 tbf_nr := tbf_nr,
Harald Welte1dcc3712017-08-01 00:05:52 +0200755 cs := cs,
756 padding := '0000'O
Harald Welteb3c226e2017-07-30 17:18:01 +0200757 },
Harald Welte3a40ec72018-03-02 20:45:04 +0100758 ul_info_abs := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200759 payload := {
760 other := l2_data
761 }
762 }
763
Harald Weltef8df4cb2018-03-10 15:15:08 +0100764 template (value) L1ctlUlMessage ts_L1CTL_DATA_ABS_REQ(octetstring l2_data, Arfcn arfcn,
Harald Welte3a40ec72018-03-02 20:45:04 +0100765 uint8_t ts, GsmFrameNumber fn,
766 L1ctlGprsCs cs := L1CTL_CS1,
767 uint8_t tbf_nr := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100768 header := ts_L1ctlHeader(L1CTL_DATA_ABS_REQ),
Harald Welte3a40ec72018-03-02 20:45:04 +0100769 ul_info := omit,
770 ul_info_tbf := omit,
771 ul_info_abs := {
772 tbf_nr := tbf_nr,
773 cs := cs,
774 ts_nr := ts,
775 padding := '00'O,
776 fn := fn,
777 arfcn := arfcn,
778 padding2 := '0000'O
779 },
780 payload := {
781 other := l2_data
782 }
783 }
784
785
Harald Welte9e4725d2017-07-16 23:18:09 +0200786 /* for matching against incoming RACH_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100787 template L1ctlDlMessage tr_L1CTL_RACH_CONF := {
788 header := tr_L1ctlHeader(L1CTL_RACH_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200789 dl_info := ?,
Harald Weltef56cc492018-04-15 10:58:43 +0200790 payload := *
Harald Welte9e4725d2017-07-16 23:18:09 +0200791 };
792
Harald Weltece6dc442018-02-21 22:00:21 +0100793 /* for matching against incoming DATA_IND */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100794 template L1ctlDlMessage tr_L1CTL_DATA_IND(template RslChannelNr chan_nr,
Harald Welte68e495b2018-02-25 00:05:57 +0100795 template RslLinkId link_id := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100796 template octetstring l2_data := ?,
797 template uint8_t num_biterr := 0,
798 template uint8_t fire_crc := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100799 header := tr_L1ctlHeader(L1CTL_DATA_IND),
Harald Welte9e4725d2017-07-16 23:18:09 +0200800 dl_info := {
801 chan_nr := chan_nr,
Harald Weltece6dc442018-02-21 22:00:21 +0100802 link_id := link_id,
Harald Welte9e4725d2017-07-16 23:18:09 +0200803 arfcn := ?,
804 frame_nr := ?,
805 rx_level := ?,
806 snr := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100807 num_biterr := num_biterr,
808 fire_crc := fire_crc
Harald Welte9e4725d2017-07-16 23:18:09 +0200809 },
810 payload := {
Harald Welte68e495b2018-02-25 00:05:57 +0100811 data_ind := {
812 payload := l2_data
813 }
Harald Welte9e4725d2017-07-16 23:18:09 +0200814 }
815 };
816
Vadim Yanitskiyf3cc6492019-06-30 16:34:30 +0700817 /* for matching against incoming TRAFFIC_IND */
818 template L1ctlDlMessage tr_L1CTL_TRAFFIC_IND(template RslChannelNr chan_nr,
819 template RslLinkId link_id := ?,
820 template octetstring frame := ?,
Vadim Yanitskiy32403122020-10-19 15:43:16 +0700821 template uint8_t num_biterr := ?,
822 template uint8_t fire_crc := ?) := {
Vadim Yanitskiyf3cc6492019-06-30 16:34:30 +0700823 header := tr_L1ctlHeader(L1CTL_TRAFFIC_IND),
824 dl_info := {
825 chan_nr := chan_nr,
826 link_id := link_id,
827 arfcn := ?,
828 frame_nr := ?,
829 rx_level := ?,
830 snr := ?,
831 num_biterr := num_biterr,
832 fire_crc := fire_crc
833 },
834 payload := {
835 traffic_ind := {
836 data := frame
837 }
838 }
839 };
840
Harald Weltee613f962018-04-18 22:38:16 +0200841 template (value) L1ctlUlMessage ts_L1CTL_CRYPTO_REQ(RslChannelNr chan_nr, uint8_t algo,
842 octetstring key) := {
843 header := ts_L1ctlHeader(L1CTL_CRYPTO_REQ),
844 ul_info := {
845 chan_nr := chan_nr,
846 link_id := ts_RslLinkID_DCCH(0),
847 padding := '0000'O
848 },
849 ul_info_tbf := omit,
850 ul_info_abs := omit,
851 payload := {
852 crypto_req := {
853 algo := algo,
854 key_len := 0, /* overwritten */
855 key := key
856 }
857 }
858 };
859
Harald Welte68e495b2018-02-25 00:05:57 +0100860 const octetstring c_DummyUI := '0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O;
861
Harald Welte7024baa2018-03-02 23:37:51 +0100862/* We use "BYTEORDER(last)" so we get little-endian integers. Unfortuantely, this also
863 switches the byte ordering in octet strings, so we need to explicitly annotate them :/ */
Harald Weltef6543322017-07-16 07:35:10 +0200864} with { encode "RAW" };