blob: 69e7dbecc571136835f7377b03f9d651f7601ecd [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,
65 CCCH_MODE_COMBINED
66 } with { variant "FIELDLENGTH(8)" };
67
68 type enumerated L1ctlNeighMode {
69 NEIGH_MODE_NONE (0),
70 NEIGH_MODE_PM,
71 NEIGH_MODE_SB
72 } with { variant "FIELDLENGTH(8)" };
73
Harald Welte1dcc3712017-08-01 00:05:52 +020074 type enumerated L1ctlGprsCs {
75 L1CTL_CS1 (1),
76 L1CTL_CS2,
77 L1CTL_CS3,
78 L1CTL_CS4,
79 L1CTL_MCS1,
80 L1CTL_MCS2,
81 L1CTL_MCS3,
82 L1CTL_MCS4,
83 L1CTL_MCS5,
84 L1CTL_MCS6,
85 L1CTL_MCS7,
86 L1CTL_MCS8,
87 L1CTL_MCS9
88 } with { variant "FIELDLENGTH(8)" };
89
Harald Weltef6543322017-07-16 07:35:10 +020090 type enumerated L1ctlResetType {
91 L1CTL_RES_T_BOOT (0),
92 L1CTL_RES_T_FULL,
93 L1CTL_RES_T_SCHED
94 } with { variant "FIELDLENGTH(8)" };
95
Harald Weltef6543322017-07-16 07:35:10 +020096 type record L1ctlHdrFlags {
97 BIT7 padding,
98 boolean f_done
99 } with { variant "" };
100
101 type record L1ctlHeader {
102 L1ctlMsgType msg_type,
103 L1ctlHdrFlags flags,
104 OCT2 padding
105 } with { variant "" };
106
Harald Weltef8df4cb2018-03-10 15:15:08 +0100107 template L1ctlHeader tr_L1ctlHeader(template L1ctlMsgType msg_type) := {
108 msg_type := msg_type,
109 flags := ?,
110 padding := ?
111 };
112
113 template (value) L1ctlHeader ts_L1ctlHeader(L1ctlMsgType msg_type) := {
Harald Welte52c713c2017-07-16 15:44:44 +0200114 msg_type := msg_type,
115 flags := { padding := '0000000'B, f_done := false },
116 padding := '0000'O
117 };
118
Harald Weltef6543322017-07-16 07:35:10 +0200119 type record L1ctlDlInfo {
Harald Welte8e4db2c2017-07-16 18:54:55 +0200120 RslChannelNr chan_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200121 RslLinkId link_id,
122 Arfcn arfcn,
Harald Welte5f0d5c82017-07-16 18:56:01 +0200123 uint32_t frame_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200124 GsmRxLev rx_level,
125 uint8_t snr,
126 uint8_t num_biterr,
127 uint8_t fire_crc
128 } with { variant "" };
129
130 type record L1ctlFbsbConf {
131 int16_t initial_freq_err,
132 uint8_t result,
133 uint8_t bsic
134 } with { variant "" };
135
136 type record L1ctlCcchModeConf {
137 L1ctlCcchMode ccch_mode,
138 OCT3 padding
139 } with { variant "" };
140
141 /* gsm48_chan_mode */
142 type uint8_t L1ctlTchMode;
143
144 type record L1ctlAudioMode {
145 BIT4 padding,
146 boolean tx_microphone,
147 boolean tx_traffic_req,
148 boolean rx_speaker,
149 boolean rx_traffic_ind
150 } with { variant "" };
151
Harald Weltef8df4cb2018-03-10 15:15:08 +0100152 template (value) L1ctlAudioMode t_L1CTL_AudioModeNone := { '0000'B, false, false, false, false };
Harald Welte66110f02017-07-16 21:05:18 +0200153
Harald Weltef6543322017-07-16 07:35:10 +0200154 type record L1ctlTchModeConf {
155 L1ctlTchMode tch_mode,
156 L1ctlAudioMode audio_mode,
157 OCT2 padding
158 } with { variant "" };
159
160 type record L1ctlDataInd {
161 octetstring payload length(23)
Harald Welte7024baa2018-03-02 23:37:51 +0100162 } with {
163 variant (payload) "BYTEORDER(first)"
164 };
Harald Weltef6543322017-07-16 07:35:10 +0200165
166 type union L1ctlDlPayload {
167 L1ctlFbsbConf fbsb_conf,
168 L1ctlCcchModeConf ccch_mode_conf,
169 L1ctlTchModeConf tch_mode_conf,
170 L1ctlDataInd data_ind,
171 L1ctlTrafficReq traffic_ind,
Harald Welte00d4dac2017-07-30 00:50:32 +0200172 L1ctlTbfCfgReq tbf_cfg_conf,
Harald Weltef6543322017-07-16 07:35:10 +0200173 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100174 } with {
175 variant (other) "BYTEORDER(first)"
176 };
Harald Weltef6543322017-07-16 07:35:10 +0200177
178 type record L1ctlDlMessage {
179 L1ctlHeader header,
180 L1ctlDlInfo dl_info optional,
Harald Weltef56cc492018-04-15 10:58:43 +0200181 L1ctlDlPayload payload optional
Harald Weltef6543322017-07-16 07:35:10 +0200182 } with { variant (dl_info) "PRESENCE(header.msg_type = L1CTL_FBSB_CONF,
183 header.msg_type = L1CTL_RACH_CONF,
184 header.msg_type = L1CTL_DATA_IND,
185 header.msg_type = L1CTL_DATA_CONF,
Harald Welte3c4cbf62018-03-30 10:31:39 +0200186 header.msg_type = L1CTL_TRAFFIC_IND,
187 header.msg_type = L1CTL_TRAFFIC_CONF)"
Harald Weltef6543322017-07-16 07:35:10 +0200188 variant (payload) "CROSSTAG(fbsb_conf, header.msg_type = L1CTL_FBSB_CONF;
189 ccch_mode_conf, header.msg_type = L1CTL_CCCH_MODE_CONF;
190 tch_mode_conf, header.msg_type = L1CTL_TCH_MODE_CONF;
191 data_ind, header.msg_type = L1CTL_DATA_IND;
192 traffic_ind, header.msg_type = L1CTL_TRAFFIC_IND;
Harald Welte00d4dac2017-07-30 00:50:32 +0200193 tbf_cfg_conf, header.msg_type = L1CTL_TBF_CFG_CONF;
Harald Weltef6543322017-07-16 07:35:10 +0200194 other, OTHERWISE;
195 )" };
196
197 external function enc_L1ctlDlMessage(in L1ctlDlMessage msg) return octetstring
198 with { extension "prototype(convert) encode(RAW)" };
199 external function dec_L1ctlDlMessage(in octetstring stream) return L1ctlDlMessage
200 with { extension "prototype(convert) decode(RAW)" };
201
202
203 type record L1ctlUlInfo {
Harald Welte8e4db2c2017-07-16 18:54:55 +0200204 RslChannelNr chan_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200205 RslLinkId link_id,
206 OCT2 padding
207 } with { variant "" };
208
Harald Welteb3c226e2017-07-30 17:18:01 +0200209 type record L1ctlUlTbfInfo {
210 uint8_t tbf_nr,
Harald Welte1dcc3712017-08-01 00:05:52 +0200211 L1ctlGprsCs cs,
212 OCT2 padding
Harald Welteb3c226e2017-07-30 17:18:01 +0200213 } with { variant "" };
214
Harald Welte3a40ec72018-03-02 20:45:04 +0100215 type record L1ctlUlAbsInfo {
216 uint8_t tbf_nr,
217 L1ctlGprsCs cs,
218 uint8_t ts_nr,
219 OCT1 padding,
Harald Welte7024baa2018-03-02 23:37:51 +0100220 uint32_le fn,
Harald Welte3a40ec72018-03-02 20:45:04 +0100221 Arfcn arfcn,
222 OCT2 padding2
223 } with { variant "" };
224
Harald Weltef6543322017-07-16 07:35:10 +0200225 type record L1ctlFbsbFlags {
226 BIT5 padding,
227 boolean sb,
228 boolean fb1,
229 boolean fb0
Harald Welte344c0cf2018-03-09 16:17:45 +0100230 } with { variant "FIELDORDER(msb)" };
Harald Weltef6543322017-07-16 07:35:10 +0200231
Harald Weltef8df4cb2018-03-10 15:15:08 +0100232 template (value) L1ctlFbsbFlags t_L1CTL_FBSB_F_ALL := {
Harald Welte66110f02017-07-16 21:05:18 +0200233 padding := '00000'B,
234 sb := true,
235 fb1 := true,
236 fb0 := true
237 };
238
Harald Weltef6543322017-07-16 07:35:10 +0200239 type record L1ctlFbsbReq {
240 Arfcn arfcn,
241 uint16_t timeout_tdma_frames,
242 uint16_t freq_err_thresh1,
243 uint16_t freq_err_thresh2,
244 uint8_t num_freqerr_avg,
245 L1ctlFbsbFlags flags,
246 uint8_t sync_info_idx,
247 L1ctlCcchMode ccch_mode,
248 GsmRxLev rxlev_exp
249 } with { variant "" };
250
251 type record L1ctlCcchModeReq {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100252 L1ctlCcchMode ccch_mode,
253 OCT3 padding
Harald Weltef6543322017-07-16 07:35:10 +0200254 } with { variant "" };
255
256 type record L1ctlTchModeReq {
257 L1ctlTchMode tch_mode,
258 L1ctlAudioMode audio_mode,
259 OCT2 padding
260 } with { variant "" };
261
262 type record L1ctlRachReq {
263 uint8_t ra,
264 uint8_t combined,
265 uint16_t offset
266 } with { variant "" };
267
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700268 type enumerated L1ctlRachSynchSeq {
269 RACH_SYNCH_SEQ_TS0 (0),
270 RACH_SYNCH_SEQ_TS1,
271 RACH_SYNCH_SEQ_TS2
272 } with { variant "FIELDLENGTH(8)" };
273
274 type record L1ctlExtRachReq {
275 uint16_t ra11,
276 L1ctlRachSynchSeq synch_seq,
277 uint8_t combined,
278 uint16_t offset
279 } with { variant "" };
280
Harald Weltef6543322017-07-16 07:35:10 +0200281 type record L1ctlParReq {
282 int8_t ta,
283 uint8_t tx_power,
284 OCT2 padding
285 } with { variant "" };
286
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200287 type record L1ctlDataReq {
288 SacchL1Header l1header optional,
289 octetstring l2_payload
290 } with { variant "" };
291
Harald Weltef6543322017-07-16 07:35:10 +0200292 type record L1ctlH1 {
293 uint8_t hsn,
294 uint8_t maio,
295 uint8_t n,
296 OCT1 padding,
297 bitstring ma length(64)
298 } with { variant "" };
299
300 type record L1ctlDmEstReq {
301 GsmTsc tsc,
302 uint8_t h,
303 Arfcn arfcn optional,
304 L1ctlH1 hopping optional,
305 L1ctlTchMode tch_mode,
306 L1ctlAudioMode audio_mode
307 } with { variant (arfcn) "PRESENCE(h = 0)"
308 variant (hopping) "PRESENCE(h = 1)" };
309
310 type record L1ctlReset {
311 L1ctlResetType reset_type,
312 OCT3 padding
313 } with { variant "" };
314
Harald Weltee613f962018-04-18 22:38:16 +0200315 type record L1CtlCryptoReq {
316 uint8_t algo,
317 uint8_t key_len,
318 octetstring key
319 } with { variant (key_len) "LENGTHTO(key)" };
320
Harald Weltef6543322017-07-16 07:35:10 +0200321
322 type record L1ctlTrafficReq {
Vadim Yanitskiye01691d2018-10-29 00:18:04 +0700323 octetstring data
Harald Welte7024baa2018-03-02 23:37:51 +0100324 } with {
325 variant (data) "BYTEORDER(first)"
326 }
Harald Weltef6543322017-07-16 07:35:10 +0200327
Harald Welte00d4dac2017-07-30 00:50:32 +0200328 type record length(8) of uint8_t TfiUsfArr;
329
330 type record L1ctlTbfCfgReq {
331 uint8_t tbf_nr,
332 boolean is_uplink,
333 OCT2 padding,
334 TfiUsfArr tfi_usf
335 } with { variant (is_uplink) "FIELDLENGTH(8)" };
336
Harald Weltef6543322017-07-16 07:35:10 +0200337 type union L1ctlUlPayload {
338 L1ctlFbsbReq fbsb_req,
339 L1ctlCcchModeReq ccch_mode_req,
340 L1ctlTchModeReq tch_mode_req,
341 L1ctlRachReq rach_req,
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700342 L1ctlExtRachReq ext_rach_req,
Harald Weltef6543322017-07-16 07:35:10 +0200343 L1ctlParReq par_req,
344 L1ctlDmEstReq dm_est_req,
345 L1ctlReset reset_req,
346 //L1ctlNeighPmReq neigh_pm_req,
Harald Weltee613f962018-04-18 22:38:16 +0200347 L1CtlCryptoReq crypto_req,
Harald Weltef6543322017-07-16 07:35:10 +0200348 L1ctlTrafficReq traffic_req,
Harald Welte00d4dac2017-07-30 00:50:32 +0200349 L1ctlTbfCfgReq tbf_cfg_req,
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200350 L1ctlDataReq data_req,
Harald Weltef6543322017-07-16 07:35:10 +0200351 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100352 } with {
353 variant (other) "BYTEORDER(first)"
354 };
Harald Weltef6543322017-07-16 07:35:10 +0200355
356 type record L1ctlUlMessage {
357 L1ctlHeader header,
358 L1ctlUlInfo ul_info optional,
Harald Welteb3c226e2017-07-30 17:18:01 +0200359 L1ctlUlTbfInfo ul_info_tbf optional,
Harald Welte3a40ec72018-03-02 20:45:04 +0100360 L1ctlUlAbsInfo ul_info_abs optional,
Harald Weltef6543322017-07-16 07:35:10 +0200361 L1ctlUlPayload payload
362 } with { variant (ul_info) "PRESENCE(header.msg_type = L1CTL_RACH_REQ,
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700363 header.msg_type = L1CTL_EXT_RACH_REQ,
Harald Weltef6543322017-07-16 07:35:10 +0200364 header.msg_type = L1CTL_PARAM_REQ,
365 header.msg_type = L1CTL_CRYPTO_REQ,
366 header.msg_type = L1CTL_DATA_REQ,
367 header.msg_type = L1CTL_DM_EST_REQ,
368 header.msg_type = L1CTL_DM_FREQ_REQ,
369 header.msg_type = L1CTL_DM_REL_REQ,
370 header.msg_type = L1CTL_TRAFFIC_REQ)"
Harald Welteb3c226e2017-07-30 17:18:01 +0200371 variant (ul_info_tbf) "PRESENCE(header.msg_type = L1CTL_DATA_TBF_REQ)"
Harald Welte3a40ec72018-03-02 20:45:04 +0100372 variant (ul_info_abs) "PRESENCE(header.msg_type = L1CTL_DATA_ABS_REQ)"
Harald Weltef6543322017-07-16 07:35:10 +0200373 variant (payload) "CROSSTAG(fbsb_req, header.msg_type = L1CTL_FBSB_REQ;
374 ccch_mode_req, header.msg_type = L1CTL_CCCH_MODE_REQ;
375 tch_mode_req, header.msg_type = L1CTL_TCH_MODE_REQ;
376 rach_req, header.msg_type = L1CTL_RACH_REQ;
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700377 ext_rach_req, header.msg_type = L1CTL_EXT_RACH_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200378 par_req, header.msg_type = L1CTL_PARAM_REQ;
379 dm_est_req, header.msg_type = L1CTL_DM_EST_REQ;
380 reset_req, header.msg_type = L1CTL_RESET_REQ;
Harald Weltee613f962018-04-18 22:38:16 +0200381 crypto_req, header.msg_type = L1CTL_CRYPTO_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200382 traffic_req, header.msg_type = L1CTL_TRAFFIC_REQ;
Harald Welte00d4dac2017-07-30 00:50:32 +0200383 tbf_cfg_req, header.msg_type = L1CTL_TBF_CFG_REQ;
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200384 data_req, header.msg_type = L1CTL_DATA_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200385 other, OTHERWISE;
386 )" };
387
388 external function enc_L1ctlUlMessage(in L1ctlUlMessage msg) return octetstring
389 with { extension "prototype(convert) encode(RAW)" };
390 external function dec_L1ctlUlMessage(in octetstring stream) return L1ctlUlMessage
391 with { extension "prototype(convert) decode(RAW)" };
392
Harald Welte52c713c2017-07-16 15:44:44 +0200393 type record L1ctlUlMessageLV {
394 uint16_t len,
395 L1ctlUlMessage msg
396 } with { variant (len) "LENGTHTO(msg)" };
397
398 external function enc_L1ctlUlMessageLV(in L1ctlUlMessageLV msg) return octetstring
399 with { extension "prototype(convert) encode(RAW)" };
400 external function dec_L1ctlUlMessageLV(in octetstring stream) return L1ctlUlMessageLV
401 with { extension "prototype(convert) decode(RAW)" };
402
403 type record L1ctlDlMessageLV {
404 uint16_t len,
405 L1ctlDlMessage msg
406 } with { variant (len) "LENGTHTO(msg)" };
407
408 external function enc_L1ctlDlMessageLV(in L1ctlDlMessageLV msg) return octetstring
409 with { extension "prototype(convert) encode(RAW)" };
410 external function dec_L1ctlDlMessageLV(in octetstring stream) return L1ctlDlMessageLV
411 with { extension "prototype(convert) decode(RAW)" };
412
413
Harald Welte9e4725d2017-07-16 23:18:09 +0200414
415
416 /* for generating RESET_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100417 template (value) L1ctlUlMessage t_L1ctlResetReq(L1ctlResetType rst_type) := {
418 header := ts_L1ctlHeader(L1CTL_RESET_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200419 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200420 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100421 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200422 payload := {
423 reset_req := {
424 reset_type := rst_type,
425 padding := '000000'O
426 }
427 }
428 };
429
430 /* for generating FBSB_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100431 template (value) L1ctlUlMessage ts_L1CTL_FBSB_REQ(Arfcn arfcn, L1ctlFbsbFlags flags,
432 uint8_t sync_info_idx,
433 L1ctlCcchMode ccch_mode,
434 GsmRxLev rxlev_exp) := {
435 header := ts_L1ctlHeader(L1CTL_FBSB_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 fbsb_req := {
441 arfcn := arfcn,
Harald Weltea82f7e62018-02-22 18:51:33 +0100442 timeout_tdma_frames := 250, /* about 1s */
Harald Welte9e4725d2017-07-16 23:18:09 +0200443 freq_err_thresh1 := 10000,
444 freq_err_thresh2 := 800,
445 num_freqerr_avg := 3,
446 flags := flags,
447 sync_info_idx := sync_info_idx,
448 ccch_mode := ccch_mode,
449 rxlev_exp := rxlev_exp
450 }
451 }
452 };
453
454 /* for matching against incoming FBSB_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100455 template L1ctlDlMessage tr_L1CTL_FBSB_CONF(template uint8_t result) := {
456 header := tr_L1ctlHeader(L1CTL_FBSB_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200457 dl_info := ?,
458 payload := {
459 fbsb_conf := {
460 initial_freq_err := ?,
461 result := result,
462 bsic := ?
463 }
464 }
465 };
466
Harald Weltef8df4cb2018-03-10 15:15:08 +0100467 template (value) L1ctlUlMessage ts_L1CTL_CCCH_MODE_REQ(L1ctlCcchMode ccch_mode) := {
468 header := ts_L1ctlHeader(L1CTL_CCCH_MODE_REQ),
469 ul_info := omit,
470 ul_info_tbf := omit,
471 ul_info_abs := omit,
472 payload := {
473 ccch_mode_req := {
474 ccch_mode := ccch_mode,
475 padding := '000000'O
476 }
477 }
478 };
479
Harald Welte3757e602018-03-10 17:12:02 +0100480
481 template L1ctlDlMessage tr_L1CTL_MsgType(template L1ctlMsgType msg_type) := {
482 header := tr_L1ctlHeader(msg_type),
483 dl_info := *,
Harald Weltef56cc492018-04-15 10:58:43 +0200484 payload := *
Harald Welte3757e602018-03-10 17:12:02 +0100485 }
486
487 template L1ctlDlMessage tr_L1CTL_CCCH_MODE_CONF := tr_L1CTL_MsgType(L1CTL_CCCH_MODE_CONF);
Harald Weltef8df4cb2018-03-10 15:15:08 +0100488
489 template L1ctlUlMessage ts_L1CTL_RACH_REQ(uint8_t ra, uint8_t combined, uint16_t offset) := {
490 header := ts_L1ctlHeader(L1CTL_RACH_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200491 ul_info := {
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700492 /* FIXME: both RSL chan_nr and link_id should be configurable */
Harald Welte9e4725d2017-07-16 23:18:09 +0200493 chan_nr := t_RslChanNr_RACH(0),
494 link_id := ts_RslLinkID_DCCH(0),
495 padding := '0000'O
496 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200497 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100498 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200499 payload := {
500 rach_req := {
501 ra := ra,
502 combined := combined,
503 offset := offset
504 }
505 }
506 }
507
Vadim Yanitskiy5c836792019-04-22 05:45:03 +0700508 template L1ctlUlMessage ts_L1CTL_EXT_RACH_REQ(
509 uint16_t ra11, L1ctlRachSynchSeq seq,
510 uint8_t combined, uint16_t offset
511 ) := {
512 header := ts_L1ctlHeader(L1CTL_EXT_RACH_REQ),
513 ul_info := {
514 /* FIXME: both RSL chan_nr and link_id should be configurable */
515 chan_nr := t_RslChanNr_RACH(0),
516 link_id := ts_RslLinkID_DCCH(0),
517 padding := '0000'O
518 },
519 ul_info_tbf := omit,
520 ul_info_abs := omit,
521 payload := {
522 ext_rach_req := {
523 ra11 := ra11,
524 synch_seq := seq,
525 combined := combined,
526 offset := offset
527 }
528 }
529 }
530
Harald Weltef8df4cb2018-03-10 15:15:08 +0100531 template L1ctlUlMessage ts_L1CTL_PAR_REQ(uint8_t ta, uint8_t tx_power) := {
532 header := ts_L1ctlHeader(L1CTL_PARAM_REQ),
Harald Welte37052732018-03-09 19:38:46 +0100533 ul_info := {
534 chan_nr := t_RslChanNr_RACH(0),
535 link_id := ts_RslLinkID_DCCH(0),
536 padding := '0000'O
537 },
538 ul_info_tbf := omit,
539 ul_info_abs := omit,
540 payload := {
541 par_req := {
542 ta := ta,
543 tx_power := tx_power,
544 padding := '0000'O
545 }
546 }
547 }
548
Harald Weltef8df4cb2018-03-10 15:15:08 +0100549 template L1ctlUlMessage ts_L1CTL_DM_EST_REQ(Arfcn arfcn, RslChannelNr chan_nr, GsmTsc tsc) := {
550 header := ts_L1ctlHeader(L1CTL_DM_EST_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200551 ul_info := {
552 chan_nr := chan_nr,
553 link_id := ts_RslLinkID_DCCH(0),
554 padding := '0000'O
555 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200556 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100557 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200558 payload := {
559 dm_est_req := {
560 tsc := tsc,
561 h := 0,
562 arfcn := arfcn,
563 hopping := omit,
564 tch_mode := 0,
565 audio_mode := t_L1CTL_AudioModeNone
566 }
567 }
568 }
569
Harald Weltef8df4cb2018-03-10 15:15:08 +0100570 template L1ctlUlMessage ts_L1CTL_DM_REL_REQ(RslChannelNr chan_nr) := {
571 header := ts_L1ctlHeader(L1CTL_DM_REL_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200572 ul_info := {
573 chan_nr := chan_nr,
574 link_id := ts_RslLinkID_DCCH(0),
575 padding := '0000'O
576 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200577 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100578 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200579 payload := {
580 other := ''O
581 }
582 }
583
Harald Weltef8df4cb2018-03-10 15:15:08 +0100584 template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ(template (value) RslChannelNr chan_nr,
585 template (value) RslLinkId link_id,
586 octetstring l2_data) := {
587 header := ts_L1ctlHeader(L1CTL_DATA_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200588 ul_info := {
589 chan_nr := chan_nr,
590 link_id := link_id,
591 padding := '0000'O
592 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200593 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100594 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200595 payload := {
596 other := l2_data
597 }
598 }
599
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200600 template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ_SACCH(template (value) RslChannelNr chan_nr,
601 template (value) RslLinkId link_id,
602 L1ctlDataReq data_req) := {
603 header := ts_L1ctlHeader(L1CTL_DATA_REQ),
604 ul_info := {
605 chan_nr := chan_nr,
606 link_id := link_id,
607 padding := '0000'O
608 },
609 ul_info_tbf := omit,
610 ul_info_abs := omit,
611 payload := {
612 data_req := data_req
613 }
614 }
615
Harald Weltef8df4cb2018-03-10 15:15:08 +0100616 template (value) L1ctlUlMessage ts_L1CTL_TBF_CFG_REQ(boolean is_uplink, TfiUsfArr tfi_usf) := {
617 header := ts_L1ctlHeader(L1CTL_TBF_CFG_REQ),
Harald Welte00d4dac2017-07-30 00:50:32 +0200618 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200619 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100620 ul_info_abs := omit,
Harald Welte00d4dac2017-07-30 00:50:32 +0200621 payload := {
622 tbf_cfg_req := {
623 tbf_nr := 0,
624 is_uplink := is_uplink,
625 padding := '0000'O,
626 tfi_usf := tfi_usf
627 }
628 }
629 };
630
Harald Weltef8df4cb2018-03-10 15:15:08 +0100631 template L1ctlDlMessage tr_L1CTL_TBF_CFG_CONF(template boolean is_uplink) := {
632 header := tr_L1ctlHeader(L1CTL_TBF_CFG_CONF),
Harald Welte00d4dac2017-07-30 00:50:32 +0200633 dl_info := omit,
634 payload := {
635 tbf_cfg_conf := {
636 tbf_nr := 0,
637 is_uplink := is_uplink,
638 padding := ?,
639 tfi_usf := ?
640 }
641 }
642 };
643
Harald Weltef8df4cb2018-03-10 15:15:08 +0100644 template (value) L1ctlUlMessage ts_L1CTL_DATA_TBF_REQ(octetstring l2_data,
645 L1ctlGprsCs cs := L1CTL_CS1,
646 uint8_t tbf_nr := 0) := {
647 header := ts_L1ctlHeader(L1CTL_DATA_TBF_REQ),
Harald Welteb3c226e2017-07-30 17:18:01 +0200648 ul_info := omit,
649 ul_info_tbf := {
650 tbf_nr := tbf_nr,
Harald Welte1dcc3712017-08-01 00:05:52 +0200651 cs := cs,
652 padding := '0000'O
Harald Welteb3c226e2017-07-30 17:18:01 +0200653 },
Harald Welte3a40ec72018-03-02 20:45:04 +0100654 ul_info_abs := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200655 payload := {
656 other := l2_data
657 }
658 }
659
Harald Weltef8df4cb2018-03-10 15:15:08 +0100660 template (value) L1ctlUlMessage ts_L1CTL_DATA_ABS_REQ(octetstring l2_data, Arfcn arfcn,
Harald Welte3a40ec72018-03-02 20:45:04 +0100661 uint8_t ts, GsmFrameNumber fn,
662 L1ctlGprsCs cs := L1CTL_CS1,
663 uint8_t tbf_nr := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100664 header := ts_L1ctlHeader(L1CTL_DATA_ABS_REQ),
Harald Welte3a40ec72018-03-02 20:45:04 +0100665 ul_info := omit,
666 ul_info_tbf := omit,
667 ul_info_abs := {
668 tbf_nr := tbf_nr,
669 cs := cs,
670 ts_nr := ts,
671 padding := '00'O,
672 fn := fn,
673 arfcn := arfcn,
674 padding2 := '0000'O
675 },
676 payload := {
677 other := l2_data
678 }
679 }
680
681
Harald Welte9e4725d2017-07-16 23:18:09 +0200682 /* for matching against incoming RACH_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100683 template L1ctlDlMessage tr_L1CTL_RACH_CONF := {
684 header := tr_L1ctlHeader(L1CTL_RACH_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200685 dl_info := ?,
Harald Weltef56cc492018-04-15 10:58:43 +0200686 payload := *
Harald Welte9e4725d2017-07-16 23:18:09 +0200687 };
688
Harald Weltece6dc442018-02-21 22:00:21 +0100689 /* for matching against incoming DATA_IND */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100690 template L1ctlDlMessage tr_L1CTL_DATA_IND(template RslChannelNr chan_nr,
Harald Welte68e495b2018-02-25 00:05:57 +0100691 template RslLinkId link_id := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100692 template octetstring l2_data := ?,
693 template uint8_t num_biterr := 0,
694 template uint8_t fire_crc := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100695 header := tr_L1ctlHeader(L1CTL_DATA_IND),
Harald Welte9e4725d2017-07-16 23:18:09 +0200696 dl_info := {
697 chan_nr := chan_nr,
Harald Weltece6dc442018-02-21 22:00:21 +0100698 link_id := link_id,
Harald Welte9e4725d2017-07-16 23:18:09 +0200699 arfcn := ?,
700 frame_nr := ?,
701 rx_level := ?,
702 snr := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100703 num_biterr := num_biterr,
704 fire_crc := fire_crc
Harald Welte9e4725d2017-07-16 23:18:09 +0200705 },
706 payload := {
Harald Welte68e495b2018-02-25 00:05:57 +0100707 data_ind := {
708 payload := l2_data
709 }
Harald Welte9e4725d2017-07-16 23:18:09 +0200710 }
711 };
712
Harald Weltee613f962018-04-18 22:38:16 +0200713 template (value) L1ctlUlMessage ts_L1CTL_CRYPTO_REQ(RslChannelNr chan_nr, uint8_t algo,
714 octetstring key) := {
715 header := ts_L1ctlHeader(L1CTL_CRYPTO_REQ),
716 ul_info := {
717 chan_nr := chan_nr,
718 link_id := ts_RslLinkID_DCCH(0),
719 padding := '0000'O
720 },
721 ul_info_tbf := omit,
722 ul_info_abs := omit,
723 payload := {
724 crypto_req := {
725 algo := algo,
726 key_len := 0, /* overwritten */
727 key := key
728 }
729 }
730 };
731
Harald Welte88849c62017-07-30 17:19:41 +0200732 template ImmediateAssignment t_IMM_ASS(uint8_t ra, GsmFrameNumber fn) := {
733 ded_or_tbf := ?,
734 page_mode := ?,
735 chan_desc := *,
736 pkt_chan_desc := *,
737 req_ref := f_compute_ReqRef(ra, fn),
738 timing_advance := ?,
739 mobile_allocation := ?,
740 rest_octets:= ?
741 };
742
743 template GsmRrMessage t_RR_IMM_ASS(uint8_t ra, GsmFrameNumber fn) := {
Harald Welte9e4725d2017-07-16 23:18:09 +0200744 header := t_RrHeader(IMMEDIATE_ASSIGNMENT, ?),
745 payload := {
Harald Welte88849c62017-07-30 17:19:41 +0200746 imm_ass := t_IMM_ASS(ra, fn)
Harald Welte9e4725d2017-07-16 23:18:09 +0200747 }
748 };
749
Harald Welte68e495b2018-02-25 00:05:57 +0100750 const octetstring c_DummyUI := '0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O;
751
Harald Welte7024baa2018-03-02 23:37:51 +0100752/* We use "BYTEORDER(last)" so we get little-endian integers. Unfortuantely, this also
753 switches the byte ordering in octet strings, so we need to explicitly annotate them :/ */
Harald Weltef6543322017-07-16 07:35:10 +0200754} with { encode "RAW" };