blob: 03ec23f422eb4213313b20bac58f83077d686ceb [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
Vadim Yanitskiy16185832020-10-19 21:20:43 +0700172 /* Traffic forwarding mode (see TRAFFIC.{req,cnf,ind} messages) */
173 template (value) L1ctlAudioMode t_L1CTL_AudioModeFwd
174 modifies t_L1CTL_AudioModeNone := {
175 tx_traffic_req := true,
176 rx_traffic_ind := true
177 };
178
Harald Weltef6543322017-07-16 07:35:10 +0200179 type record L1ctlTchModeConf {
180 L1ctlTchMode tch_mode,
181 L1ctlAudioMode audio_mode,
182 OCT2 padding
183 } with { variant "" };
184
185 type record L1ctlDataInd {
Vadim Yanitskiy2a92e2a2019-05-28 21:13:35 +0700186 octetstring payload
Harald Welte7024baa2018-03-02 23:37:51 +0100187 } with {
188 variant (payload) "BYTEORDER(first)"
189 };
Harald Weltef6543322017-07-16 07:35:10 +0200190
191 type union L1ctlDlPayload {
192 L1ctlFbsbConf fbsb_conf,
193 L1ctlCcchModeConf ccch_mode_conf,
194 L1ctlTchModeConf tch_mode_conf,
195 L1ctlDataInd data_ind,
196 L1ctlTrafficReq traffic_ind,
Harald Welte00d4dac2017-07-30 00:50:32 +0200197 L1ctlTbfCfgReq tbf_cfg_conf,
Harald Weltef6543322017-07-16 07:35:10 +0200198 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100199 } with {
200 variant (other) "BYTEORDER(first)"
201 };
Harald Weltef6543322017-07-16 07:35:10 +0200202
203 type record L1ctlDlMessage {
204 L1ctlHeader header,
205 L1ctlDlInfo dl_info optional,
Harald Weltef56cc492018-04-15 10:58:43 +0200206 L1ctlDlPayload payload optional
Harald Weltef6543322017-07-16 07:35:10 +0200207 } with { variant (dl_info) "PRESENCE(header.msg_type = L1CTL_FBSB_CONF,
208 header.msg_type = L1CTL_RACH_CONF,
209 header.msg_type = L1CTL_DATA_IND,
210 header.msg_type = L1CTL_DATA_CONF,
Harald Welte3c4cbf62018-03-30 10:31:39 +0200211 header.msg_type = L1CTL_TRAFFIC_IND,
212 header.msg_type = L1CTL_TRAFFIC_CONF)"
Harald Weltef6543322017-07-16 07:35:10 +0200213 variant (payload) "CROSSTAG(fbsb_conf, header.msg_type = L1CTL_FBSB_CONF;
214 ccch_mode_conf, header.msg_type = L1CTL_CCCH_MODE_CONF;
215 tch_mode_conf, header.msg_type = L1CTL_TCH_MODE_CONF;
216 data_ind, header.msg_type = L1CTL_DATA_IND;
217 traffic_ind, header.msg_type = L1CTL_TRAFFIC_IND;
Harald Welte00d4dac2017-07-30 00:50:32 +0200218 tbf_cfg_conf, header.msg_type = L1CTL_TBF_CFG_CONF;
Harald Weltef6543322017-07-16 07:35:10 +0200219 other, OTHERWISE;
220 )" };
221
222 external function enc_L1ctlDlMessage(in L1ctlDlMessage msg) return octetstring
223 with { extension "prototype(convert) encode(RAW)" };
224 external function dec_L1ctlDlMessage(in octetstring stream) return L1ctlDlMessage
225 with { extension "prototype(convert) decode(RAW)" };
226
227
228 type record L1ctlUlInfo {
Harald Welte8e4db2c2017-07-16 18:54:55 +0200229 RslChannelNr chan_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200230 RslLinkId link_id,
231 OCT2 padding
232 } with { variant "" };
233
Harald Welteb3c226e2017-07-30 17:18:01 +0200234 type record L1ctlUlTbfInfo {
235 uint8_t tbf_nr,
Harald Welte1dcc3712017-08-01 00:05:52 +0200236 L1ctlGprsCs cs,
237 OCT2 padding
Harald Welteb3c226e2017-07-30 17:18:01 +0200238 } with { variant "" };
239
Harald Welte3a40ec72018-03-02 20:45:04 +0100240 type record L1ctlUlAbsInfo {
241 uint8_t tbf_nr,
242 L1ctlGprsCs cs,
243 uint8_t ts_nr,
244 OCT1 padding,
Harald Welte7024baa2018-03-02 23:37:51 +0100245 uint32_le fn,
Harald Welte3a40ec72018-03-02 20:45:04 +0100246 Arfcn arfcn,
247 OCT2 padding2
248 } with { variant "" };
249
Harald Weltef6543322017-07-16 07:35:10 +0200250 type record L1ctlFbsbFlags {
251 BIT5 padding,
252 boolean sb,
253 boolean fb1,
254 boolean fb0
Harald Welte344c0cf2018-03-09 16:17:45 +0100255 } with { variant "FIELDORDER(msb)" };
Harald Weltef6543322017-07-16 07:35:10 +0200256
Harald Weltef8df4cb2018-03-10 15:15:08 +0100257 template (value) L1ctlFbsbFlags t_L1CTL_FBSB_F_ALL := {
Harald Welte66110f02017-07-16 21:05:18 +0200258 padding := '00000'B,
259 sb := true,
260 fb1 := true,
261 fb0 := true
262 };
263
Harald Weltef6543322017-07-16 07:35:10 +0200264 type record L1ctlFbsbReq {
265 Arfcn arfcn,
266 uint16_t timeout_tdma_frames,
267 uint16_t freq_err_thresh1,
268 uint16_t freq_err_thresh2,
269 uint8_t num_freqerr_avg,
270 L1ctlFbsbFlags flags,
271 uint8_t sync_info_idx,
272 L1ctlCcchMode ccch_mode,
273 GsmRxLev rxlev_exp
274 } with { variant "" };
275
276 type record L1ctlCcchModeReq {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100277 L1ctlCcchMode ccch_mode,
278 OCT3 padding
Harald Weltef6543322017-07-16 07:35:10 +0200279 } with { variant "" };
280
281 type record L1ctlTchModeReq {
282 L1ctlTchMode tch_mode,
283 L1ctlAudioMode audio_mode,
Vadim Yanitskiy7ce605f2020-10-19 16:04:38 +0700284 L1ctlLoopMode loop_mode,
285 OCT1 padding
Harald Weltef6543322017-07-16 07:35:10 +0200286 } with { variant "" };
287
288 type record L1ctlRachReq {
289 uint8_t ra,
290 uint8_t combined,
291 uint16_t offset
292 } with { variant "" };
293
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700294 type enumerated L1ctlRachSynchSeq {
295 RACH_SYNCH_SEQ_TS0 (0),
296 RACH_SYNCH_SEQ_TS1,
297 RACH_SYNCH_SEQ_TS2
298 } with { variant "FIELDLENGTH(8)" };
299
300 type record L1ctlExtRachReq {
301 uint16_t ra11,
302 L1ctlRachSynchSeq synch_seq,
303 uint8_t combined,
304 uint16_t offset
305 } with { variant "" };
306
Harald Weltef6543322017-07-16 07:35:10 +0200307 type record L1ctlParReq {
308 int8_t ta,
309 uint8_t tx_power,
310 OCT2 padding
311 } with { variant "" };
312
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200313 type record L1ctlDataReq {
314 SacchL1Header l1header optional,
315 octetstring l2_payload
316 } with { variant "" };
317
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700318 type record L1ctlH0 {
319 uint8_t h,
320 Arfcn arfcn,
321 octetstring padding length(130)
322 } with { variant "" };
323
Vadim Yanitskiye8ea3ee2020-05-27 13:29:48 +0700324 type record length(0..64) of Arfcn L1ctlMA;
Harald Weltef6543322017-07-16 07:35:10 +0200325 type record L1ctlH1 {
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700326 uint8_t h,
Harald Weltef6543322017-07-16 07:35:10 +0200327 uint8_t hsn,
328 uint8_t maio,
329 uint8_t n,
Vadim Yanitskiye8ea3ee2020-05-27 13:29:48 +0700330 OCT1 spare,
331 L1ctlMA ma,
332 octetstring padding
333 } with {
334 variant (n) "LENGTHTO(ma)"
335 variant (n) "UNIT(elements)"
336 /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=562849.
337 * TL;DR The reference point of the PADDING attribute is the beginning
338 * of the message, not the beginning of the type/field it's applied on.
339 * Therefore we cannot use it here, and have to add padding manually.
340 * variant (ma) "PADDING(128)" */
341 };
Harald Weltef6543322017-07-16 07:35:10 +0200342
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700343 type union L1ctlH0H1 {
344 L1ctlH0 h0,
345 L1ctlH1 h1
346 } with { variant "TAG(h0, h = 0; h1, h = 1)" };
347
Harald Weltef6543322017-07-16 07:35:10 +0200348 type record L1ctlDmEstReq {
349 GsmTsc tsc,
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700350 L1ctlH0H1 h0h1,
Harald Weltef6543322017-07-16 07:35:10 +0200351 L1ctlTchMode tch_mode,
352 L1ctlAudioMode audio_mode
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700353 } with { variant "" };
Harald Weltef6543322017-07-16 07:35:10 +0200354
355 type record L1ctlReset {
356 L1ctlResetType reset_type,
357 OCT3 padding
358 } with { variant "" };
359
Harald Weltee613f962018-04-18 22:38:16 +0200360 type record L1CtlCryptoReq {
361 uint8_t algo,
362 uint8_t key_len,
363 octetstring key
364 } with { variant (key_len) "LENGTHTO(key)" };
365
Harald Weltef6543322017-07-16 07:35:10 +0200366
367 type record L1ctlTrafficReq {
Vadim Yanitskiye01691d2018-10-29 00:18:04 +0700368 octetstring data
Harald Welte7024baa2018-03-02 23:37:51 +0100369 } with {
370 variant (data) "BYTEORDER(first)"
371 }
Harald Weltef6543322017-07-16 07:35:10 +0200372
Harald Welte00d4dac2017-07-30 00:50:32 +0200373 type record length(8) of uint8_t TfiUsfArr;
374
375 type record L1ctlTbfCfgReq {
376 uint8_t tbf_nr,
377 boolean is_uplink,
378 OCT2 padding,
379 TfiUsfArr tfi_usf
380 } with { variant (is_uplink) "FIELDLENGTH(8)" };
381
Harald Weltef6543322017-07-16 07:35:10 +0200382 type union L1ctlUlPayload {
383 L1ctlFbsbReq fbsb_req,
384 L1ctlCcchModeReq ccch_mode_req,
385 L1ctlTchModeReq tch_mode_req,
386 L1ctlRachReq rach_req,
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700387 L1ctlExtRachReq ext_rach_req,
Harald Weltef6543322017-07-16 07:35:10 +0200388 L1ctlParReq par_req,
389 L1ctlDmEstReq dm_est_req,
390 L1ctlReset reset_req,
391 //L1ctlNeighPmReq neigh_pm_req,
Harald Weltee613f962018-04-18 22:38:16 +0200392 L1CtlCryptoReq crypto_req,
Harald Weltef6543322017-07-16 07:35:10 +0200393 L1ctlTrafficReq traffic_req,
Harald Welte00d4dac2017-07-30 00:50:32 +0200394 L1ctlTbfCfgReq tbf_cfg_req,
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200395 L1ctlDataReq data_req,
Harald Weltef6543322017-07-16 07:35:10 +0200396 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100397 } with {
398 variant (other) "BYTEORDER(first)"
399 };
Harald Weltef6543322017-07-16 07:35:10 +0200400
401 type record L1ctlUlMessage {
402 L1ctlHeader header,
403 L1ctlUlInfo ul_info optional,
Harald Welteb3c226e2017-07-30 17:18:01 +0200404 L1ctlUlTbfInfo ul_info_tbf optional,
Harald Welte3a40ec72018-03-02 20:45:04 +0100405 L1ctlUlAbsInfo ul_info_abs optional,
Harald Weltef6543322017-07-16 07:35:10 +0200406 L1ctlUlPayload payload
407 } with { variant (ul_info) "PRESENCE(header.msg_type = L1CTL_RACH_REQ,
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700408 header.msg_type = L1CTL_EXT_RACH_REQ,
Harald Weltef6543322017-07-16 07:35:10 +0200409 header.msg_type = L1CTL_PARAM_REQ,
410 header.msg_type = L1CTL_CRYPTO_REQ,
411 header.msg_type = L1CTL_DATA_REQ,
412 header.msg_type = L1CTL_DM_EST_REQ,
413 header.msg_type = L1CTL_DM_FREQ_REQ,
414 header.msg_type = L1CTL_DM_REL_REQ,
415 header.msg_type = L1CTL_TRAFFIC_REQ)"
Harald Welteb3c226e2017-07-30 17:18:01 +0200416 variant (ul_info_tbf) "PRESENCE(header.msg_type = L1CTL_DATA_TBF_REQ)"
Harald Welte3a40ec72018-03-02 20:45:04 +0100417 variant (ul_info_abs) "PRESENCE(header.msg_type = L1CTL_DATA_ABS_REQ)"
Harald Weltef6543322017-07-16 07:35:10 +0200418 variant (payload) "CROSSTAG(fbsb_req, header.msg_type = L1CTL_FBSB_REQ;
419 ccch_mode_req, header.msg_type = L1CTL_CCCH_MODE_REQ;
420 tch_mode_req, header.msg_type = L1CTL_TCH_MODE_REQ;
421 rach_req, header.msg_type = L1CTL_RACH_REQ;
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700422 ext_rach_req, header.msg_type = L1CTL_EXT_RACH_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200423 par_req, header.msg_type = L1CTL_PARAM_REQ;
424 dm_est_req, header.msg_type = L1CTL_DM_EST_REQ;
425 reset_req, header.msg_type = L1CTL_RESET_REQ;
Harald Weltee613f962018-04-18 22:38:16 +0200426 crypto_req, header.msg_type = L1CTL_CRYPTO_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200427 traffic_req, header.msg_type = L1CTL_TRAFFIC_REQ;
Harald Welte00d4dac2017-07-30 00:50:32 +0200428 tbf_cfg_req, header.msg_type = L1CTL_TBF_CFG_REQ;
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200429 data_req, header.msg_type = L1CTL_DATA_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200430 other, OTHERWISE;
431 )" };
432
433 external function enc_L1ctlUlMessage(in L1ctlUlMessage msg) return octetstring
434 with { extension "prototype(convert) encode(RAW)" };
435 external function dec_L1ctlUlMessage(in octetstring stream) return L1ctlUlMessage
436 with { extension "prototype(convert) decode(RAW)" };
437
Harald Welte52c713c2017-07-16 15:44:44 +0200438 type record L1ctlUlMessageLV {
439 uint16_t len,
440 L1ctlUlMessage msg
441 } with { variant (len) "LENGTHTO(msg)" };
442
443 external function enc_L1ctlUlMessageLV(in L1ctlUlMessageLV msg) return octetstring
444 with { extension "prototype(convert) encode(RAW)" };
445 external function dec_L1ctlUlMessageLV(in octetstring stream) return L1ctlUlMessageLV
446 with { extension "prototype(convert) decode(RAW)" };
447
448 type record L1ctlDlMessageLV {
449 uint16_t len,
450 L1ctlDlMessage msg
451 } with { variant (len) "LENGTHTO(msg)" };
452
453 external function enc_L1ctlDlMessageLV(in L1ctlDlMessageLV msg) return octetstring
454 with { extension "prototype(convert) encode(RAW)" };
455 external function dec_L1ctlDlMessageLV(in octetstring stream) return L1ctlDlMessageLV
456 with { extension "prototype(convert) decode(RAW)" };
457
458
Harald Welte9e4725d2017-07-16 23:18:09 +0200459
460
461 /* for generating RESET_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100462 template (value) L1ctlUlMessage t_L1ctlResetReq(L1ctlResetType rst_type) := {
463 header := ts_L1ctlHeader(L1CTL_RESET_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200464 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200465 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100466 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200467 payload := {
468 reset_req := {
469 reset_type := rst_type,
470 padding := '000000'O
471 }
472 }
473 };
474
475 /* for generating FBSB_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100476 template (value) L1ctlUlMessage ts_L1CTL_FBSB_REQ(Arfcn arfcn, L1ctlFbsbFlags flags,
477 uint8_t sync_info_idx,
478 L1ctlCcchMode ccch_mode,
479 GsmRxLev rxlev_exp) := {
480 header := ts_L1ctlHeader(L1CTL_FBSB_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200481 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200482 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100483 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200484 payload := {
485 fbsb_req := {
486 arfcn := arfcn,
Harald Weltea82f7e62018-02-22 18:51:33 +0100487 timeout_tdma_frames := 250, /* about 1s */
Harald Welte9e4725d2017-07-16 23:18:09 +0200488 freq_err_thresh1 := 10000,
489 freq_err_thresh2 := 800,
490 num_freqerr_avg := 3,
491 flags := flags,
492 sync_info_idx := sync_info_idx,
493 ccch_mode := ccch_mode,
494 rxlev_exp := rxlev_exp
495 }
496 }
497 };
498
499 /* for matching against incoming FBSB_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100500 template L1ctlDlMessage tr_L1CTL_FBSB_CONF(template uint8_t result) := {
501 header := tr_L1ctlHeader(L1CTL_FBSB_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200502 dl_info := ?,
503 payload := {
504 fbsb_conf := {
505 initial_freq_err := ?,
506 result := result,
507 bsic := ?
508 }
509 }
510 };
511
Harald Weltef8df4cb2018-03-10 15:15:08 +0100512 template (value) L1ctlUlMessage ts_L1CTL_CCCH_MODE_REQ(L1ctlCcchMode ccch_mode) := {
513 header := ts_L1ctlHeader(L1CTL_CCCH_MODE_REQ),
514 ul_info := omit,
515 ul_info_tbf := omit,
516 ul_info_abs := omit,
517 payload := {
518 ccch_mode_req := {
519 ccch_mode := ccch_mode,
520 padding := '000000'O
521 }
522 }
523 };
524
Vadim Yanitskiy3b1fae42020-10-19 16:16:41 +0700525 template (value) L1ctlUlMessage
526 ts_L1CTL_TCH_MODE_REQ(template (value) L1ctlTchMode tch_mode := L1CTL_CHAN_MODE_SIGN,
Vadim Yanitskiy16185832020-10-19 21:20:43 +0700527 template (value) L1ctlAudioMode audio_mode := t_L1CTL_AudioModeFwd,
Vadim Yanitskiy3b1fae42020-10-19 16:16:41 +0700528 template (value) L1ctlLoopMode loop_mode := L1CTL_LOOP_MODE_OPEN) := {
529 header := ts_L1ctlHeader(L1CTL_TCH_MODE_REQ),
530 ul_info := omit,
531 ul_info_tbf := omit,
532 ul_info_abs := omit,
533 payload := {
534 tch_mode_req := {
535 tch_mode := tch_mode,
536 audio_mode := audio_mode,
537 loop_mode := loop_mode,
538 padding := '00'O
539 }
540 }
541 };
542
Harald Welte3757e602018-03-10 17:12:02 +0100543
544 template L1ctlDlMessage tr_L1CTL_MsgType(template L1ctlMsgType msg_type) := {
545 header := tr_L1ctlHeader(msg_type),
546 dl_info := *,
Harald Weltef56cc492018-04-15 10:58:43 +0200547 payload := *
Harald Welte3757e602018-03-10 17:12:02 +0100548 }
549
550 template L1ctlDlMessage tr_L1CTL_CCCH_MODE_CONF := tr_L1CTL_MsgType(L1CTL_CCCH_MODE_CONF);
Harald Weltef8df4cb2018-03-10 15:15:08 +0100551
Vadim Yanitskiye432ba92019-05-31 18:44:13 +0700552 template L1ctlUlMessage ts_L1CTL_RACH_REQ(uint8_t ra, uint8_t combined, uint16_t offset,
553 template (value) RslChannelNr chan_nr := ts_RslChanNr_RACH(0),
554 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0)) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100555 header := ts_L1ctlHeader(L1CTL_RACH_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200556 ul_info := {
Vadim Yanitskiye432ba92019-05-31 18:44:13 +0700557 chan_nr := chan_nr,
558 link_id := link_id,
Harald Welte9e4725d2017-07-16 23:18:09 +0200559 padding := '0000'O
560 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200561 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100562 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200563 payload := {
564 rach_req := {
565 ra := ra,
566 combined := combined,
567 offset := offset
568 }
569 }
570 }
571
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700572 template L1ctlUlMessage ts_L1CTL_EXT_RACH_REQ(
573 uint16_t ra11, L1ctlRachSynchSeq seq,
574 uint8_t combined, uint16_t offset
575 ) := {
576 header := ts_L1ctlHeader(L1CTL_EXT_RACH_REQ),
577 ul_info := {
578 /* FIXME: both RSL chan_nr and link_id should be configurable */
579 chan_nr := t_RslChanNr_RACH(0),
580 link_id := ts_RslLinkID_DCCH(0),
581 padding := '0000'O
582 },
583 ul_info_tbf := omit,
584 ul_info_abs := omit,
585 payload := {
586 ext_rach_req := {
587 ra11 := ra11,
588 synch_seq := seq,
589 combined := combined,
590 offset := offset
591 }
592 }
593 }
594
Harald Weltef8df4cb2018-03-10 15:15:08 +0100595 template L1ctlUlMessage ts_L1CTL_PAR_REQ(uint8_t ta, uint8_t tx_power) := {
596 header := ts_L1ctlHeader(L1CTL_PARAM_REQ),
Harald Welte37052732018-03-09 19:38:46 +0100597 ul_info := {
598 chan_nr := t_RslChanNr_RACH(0),
599 link_id := ts_RslLinkID_DCCH(0),
600 padding := '0000'O
601 },
602 ul_info_tbf := omit,
603 ul_info_abs := omit,
604 payload := {
605 par_req := {
606 ta := ta,
607 tx_power := tx_power,
608 padding := '0000'O
609 }
610 }
611 }
612
Vadim Yanitskiy5afe8852020-05-27 14:40:51 +0700613 /* Base template to be inherited by ts_L1CTL_DM_EST_REQ_H0 and ts_L1CTL_DM_EST_REQ_H1 */
614 private template (value) L1ctlUlMessage ts_L1CTL_DM_EST_REQ(template (value) RslChannelNr chan_nr,
615 template (value) GsmTsc tsc) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100616 header := ts_L1ctlHeader(L1CTL_DM_EST_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200617 ul_info := {
618 chan_nr := chan_nr,
619 link_id := ts_RslLinkID_DCCH(0),
620 padding := '0000'O
621 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200622 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100623 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200624 payload := {
625 dm_est_req := {
626 tsc := tsc,
Vadim Yanitskiyfe052962020-10-19 13:27:09 +0700627 tch_mode := L1CTL_CHAN_MODE_SIGN,
Vadim Yanitskiy16185832020-10-19 21:20:43 +0700628 audio_mode := t_L1CTL_AudioModeFwd
Harald Welte9e4725d2017-07-16 23:18:09 +0200629 }
630 }
631 }
632
Vadim Yanitskiy5afe8852020-05-27 14:40:51 +0700633 template (value) L1ctlUlMessage ts_L1CTL_DM_EST_REQ_H0(template (value) RslChannelNr chan_nr,
634 template (value) GsmTsc tsc,
635 template (value) GsmArfcn arfcn)
636 modifies ts_L1CTL_DM_EST_REQ := {
637 payload := {
638 dm_est_req := {
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700639 h0h1 := {
640 h0 := {
641 h := 0,
642 arfcn := { false, arfcn },
643 padding := f_pad_oct(''O, 130, '00'O)
644 }
645 }
Vadim Yanitskiy5afe8852020-05-27 14:40:51 +0700646 }
647 }
648 }
649
Vadim Yanitskiyeda90812020-05-27 14:51:18 +0700650 template (value) L1ctlUlMessage ts_L1CTL_DM_EST_REQ_H1(template (value) RslChannelNr chan_nr,
651 template (value) GsmTsc tsc,
652 template (value) uint6_t hsn,
653 template (value) uint6_t maio,
654 template (value) L1ctlMA ma)
655 modifies ts_L1CTL_DM_EST_REQ := {
656 payload := {
657 dm_est_req := {
Vadim Yanitskiy2cdb97f2020-10-19 14:17:38 +0700658 h0h1 := {
659 h1 := {
660 h := 1,
661 hsn := hsn,
662 maio := maio,
663 n := sizeof(ma),
664 spare := '00'O,
665 ma := ma,
666 /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=562849 */
667 padding := f_pad_oct(''O, (64 - sizeof(ma)) * 2, '00'O)
668 }
Vadim Yanitskiyeda90812020-05-27 14:51:18 +0700669 }
670 }
671 }
672 }
673
Harald Weltef8df4cb2018-03-10 15:15:08 +0100674 template L1ctlUlMessage ts_L1CTL_DM_REL_REQ(RslChannelNr chan_nr) := {
675 header := ts_L1ctlHeader(L1CTL_DM_REL_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200676 ul_info := {
677 chan_nr := chan_nr,
678 link_id := ts_RslLinkID_DCCH(0),
679 padding := '0000'O
680 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200681 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100682 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200683 payload := {
684 other := ''O
685 }
686 }
687
Harald Weltef8df4cb2018-03-10 15:15:08 +0100688 template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ(template (value) RslChannelNr chan_nr,
689 template (value) RslLinkId link_id,
690 octetstring l2_data) := {
691 header := ts_L1ctlHeader(L1CTL_DATA_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200692 ul_info := {
693 chan_nr := chan_nr,
694 link_id := link_id,
695 padding := '0000'O
696 },
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 Welte9e4725d2017-07-16 23:18:09 +0200699 payload := {
Vadim Yanitskiy0a8d6da2019-05-28 22:18:28 +0700700 data_req := {
701 l1header := omit,
702 l2_payload := l2_data
703 }
Harald Welte9e4725d2017-07-16 23:18:09 +0200704 }
705 }
706
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200707 template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ_SACCH(template (value) RslChannelNr chan_nr,
708 template (value) RslLinkId link_id,
Vadim Yanitskiy0a8d6da2019-05-28 22:18:28 +0700709 template (value) SacchL1Header l1h,
710 octetstring l2_data) := {
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200711 header := ts_L1ctlHeader(L1CTL_DATA_REQ),
712 ul_info := {
713 chan_nr := chan_nr,
714 link_id := link_id,
715 padding := '0000'O
716 },
717 ul_info_tbf := omit,
718 ul_info_abs := omit,
719 payload := {
Vadim Yanitskiy0a8d6da2019-05-28 22:18:28 +0700720 data_req := {
721 l1header := l1h,
722 l2_payload := l2_data
723 }
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200724 }
725 }
726
Vadim Yanitskiyf3cc6492019-06-30 16:34:30 +0700727 template (value) L1ctlUlMessage ts_L1CTL_TRAFFIC_REQ(template (value) RslChannelNr chan_nr,
728 template (value) RslLinkId link_id,
729 octetstring frame) := {
730 header := ts_L1ctlHeader(L1CTL_TRAFFIC_REQ),
731 ul_info := {
732 chan_nr := chan_nr,
733 link_id := link_id,
734 padding := '0000'O
735 },
736 ul_info_tbf := omit,
737 ul_info_abs := omit,
738 payload := {
739 traffic_req := {
740 data := frame
741 }
742 }
743 };
744
Harald Weltef8df4cb2018-03-10 15:15:08 +0100745 template (value) L1ctlUlMessage ts_L1CTL_TBF_CFG_REQ(boolean is_uplink, TfiUsfArr tfi_usf) := {
746 header := ts_L1ctlHeader(L1CTL_TBF_CFG_REQ),
Harald Welte00d4dac2017-07-30 00:50:32 +0200747 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200748 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100749 ul_info_abs := omit,
Harald Welte00d4dac2017-07-30 00:50:32 +0200750 payload := {
751 tbf_cfg_req := {
752 tbf_nr := 0,
753 is_uplink := is_uplink,
754 padding := '0000'O,
755 tfi_usf := tfi_usf
756 }
757 }
758 };
759
Harald Weltef8df4cb2018-03-10 15:15:08 +0100760 template L1ctlDlMessage tr_L1CTL_TBF_CFG_CONF(template boolean is_uplink) := {
761 header := tr_L1ctlHeader(L1CTL_TBF_CFG_CONF),
Harald Welte00d4dac2017-07-30 00:50:32 +0200762 dl_info := omit,
763 payload := {
764 tbf_cfg_conf := {
765 tbf_nr := 0,
766 is_uplink := is_uplink,
767 padding := ?,
768 tfi_usf := ?
769 }
770 }
771 };
772
Harald Weltef8df4cb2018-03-10 15:15:08 +0100773 template (value) L1ctlUlMessage ts_L1CTL_DATA_TBF_REQ(octetstring l2_data,
774 L1ctlGprsCs cs := L1CTL_CS1,
775 uint8_t tbf_nr := 0) := {
776 header := ts_L1ctlHeader(L1CTL_DATA_TBF_REQ),
Harald Welteb3c226e2017-07-30 17:18:01 +0200777 ul_info := omit,
778 ul_info_tbf := {
779 tbf_nr := tbf_nr,
Harald Welte1dcc3712017-08-01 00:05:52 +0200780 cs := cs,
781 padding := '0000'O
Harald Welteb3c226e2017-07-30 17:18:01 +0200782 },
Harald Welte3a40ec72018-03-02 20:45:04 +0100783 ul_info_abs := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200784 payload := {
785 other := l2_data
786 }
787 }
788
Harald Weltef8df4cb2018-03-10 15:15:08 +0100789 template (value) L1ctlUlMessage ts_L1CTL_DATA_ABS_REQ(octetstring l2_data, Arfcn arfcn,
Harald Welte3a40ec72018-03-02 20:45:04 +0100790 uint8_t ts, GsmFrameNumber fn,
791 L1ctlGprsCs cs := L1CTL_CS1,
792 uint8_t tbf_nr := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100793 header := ts_L1ctlHeader(L1CTL_DATA_ABS_REQ),
Harald Welte3a40ec72018-03-02 20:45:04 +0100794 ul_info := omit,
795 ul_info_tbf := omit,
796 ul_info_abs := {
797 tbf_nr := tbf_nr,
798 cs := cs,
799 ts_nr := ts,
800 padding := '00'O,
801 fn := fn,
802 arfcn := arfcn,
803 padding2 := '0000'O
804 },
805 payload := {
806 other := l2_data
807 }
808 }
809
810
Harald Welte9e4725d2017-07-16 23:18:09 +0200811 /* for matching against incoming RACH_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100812 template L1ctlDlMessage tr_L1CTL_RACH_CONF := {
813 header := tr_L1ctlHeader(L1CTL_RACH_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200814 dl_info := ?,
Harald Weltef56cc492018-04-15 10:58:43 +0200815 payload := *
Harald Welte9e4725d2017-07-16 23:18:09 +0200816 };
817
Harald Weltece6dc442018-02-21 22:00:21 +0100818 /* for matching against incoming DATA_IND */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100819 template L1ctlDlMessage tr_L1CTL_DATA_IND(template RslChannelNr chan_nr,
Harald Welte68e495b2018-02-25 00:05:57 +0100820 template RslLinkId link_id := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100821 template octetstring l2_data := ?,
822 template uint8_t num_biterr := 0,
823 template uint8_t fire_crc := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100824 header := tr_L1ctlHeader(L1CTL_DATA_IND),
Harald Welte9e4725d2017-07-16 23:18:09 +0200825 dl_info := {
826 chan_nr := chan_nr,
Harald Weltece6dc442018-02-21 22:00:21 +0100827 link_id := link_id,
Harald Welte9e4725d2017-07-16 23:18:09 +0200828 arfcn := ?,
829 frame_nr := ?,
830 rx_level := ?,
831 snr := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100832 num_biterr := num_biterr,
833 fire_crc := fire_crc
Harald Welte9e4725d2017-07-16 23:18:09 +0200834 },
835 payload := {
Harald Welte68e495b2018-02-25 00:05:57 +0100836 data_ind := {
837 payload := l2_data
838 }
Harald Welte9e4725d2017-07-16 23:18:09 +0200839 }
840 };
841
Vadim Yanitskiyf3cc6492019-06-30 16:34:30 +0700842 /* for matching against incoming TRAFFIC_IND */
843 template L1ctlDlMessage tr_L1CTL_TRAFFIC_IND(template RslChannelNr chan_nr,
844 template RslLinkId link_id := ?,
845 template octetstring frame := ?,
Vadim Yanitskiy32403122020-10-19 15:43:16 +0700846 template uint8_t num_biterr := ?,
847 template uint8_t fire_crc := ?) := {
Vadim Yanitskiyf3cc6492019-06-30 16:34:30 +0700848 header := tr_L1ctlHeader(L1CTL_TRAFFIC_IND),
849 dl_info := {
850 chan_nr := chan_nr,
851 link_id := link_id,
852 arfcn := ?,
853 frame_nr := ?,
854 rx_level := ?,
855 snr := ?,
856 num_biterr := num_biterr,
857 fire_crc := fire_crc
858 },
859 payload := {
860 traffic_ind := {
861 data := frame
862 }
863 }
864 };
865
Harald Weltee613f962018-04-18 22:38:16 +0200866 template (value) L1ctlUlMessage ts_L1CTL_CRYPTO_REQ(RslChannelNr chan_nr, uint8_t algo,
867 octetstring key) := {
868 header := ts_L1ctlHeader(L1CTL_CRYPTO_REQ),
869 ul_info := {
870 chan_nr := chan_nr,
871 link_id := ts_RslLinkID_DCCH(0),
872 padding := '0000'O
873 },
874 ul_info_tbf := omit,
875 ul_info_abs := omit,
876 payload := {
877 crypto_req := {
878 algo := algo,
879 key_len := 0, /* overwritten */
880 key := key
881 }
882 }
883 };
884
Harald Welte68e495b2018-02-25 00:05:57 +0100885 const octetstring c_DummyUI := '0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O;
886
Harald Welte7024baa2018-03-02 23:37:51 +0100887/* We use "BYTEORDER(last)" so we get little-endian integers. Unfortuantely, this also
888 switches the byte ordering in octet strings, so we need to explicitly annotate them :/ */
Harald Weltef6543322017-07-16 07:35:10 +0200889} with { encode "RAW" };