blob: ae800b07ad1cf1a6ad00d8b71f9287ede43caf1e [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
3 * (C) 2010 by Harald Welte + Holger Hans Peter Freyther */
4module L1CTL_Types {
5
6 import from General_Types all;
7 import from GSM_Types all;
Harald Welte9419c8a2017-07-30 04:07:05 +02008 import from GSM_RR_Types all;
Harald Weltef6543322017-07-16 07:35:10 +02009 import from Osmocom_Types all;
10
Harald Welte7024baa2018-03-02 23:37:51 +010011 type uint32_t uint32_le with { variant "BYTEORDER(first)" };
12
Harald Weltef6543322017-07-16 07:35:10 +020013 type enumerated L1ctlMsgType {
14 L1CTL_NONE,
15 L1CTL_FBSB_REQ,
16 L1CTL_FBSB_CONF,
17 L1CTL_DATA_IND,
18 L1CTL_RACH_REQ,
19 L1CTL_DM_EST_REQ,
20 L1CTL_DATA_REQ,
21 L1CTL_RESET_IND,
22 L1CTL_PM_REQ, /* power measurement */
23 L1CTL_PM_CONF, /* power measurement */
24 L1CTL_ECHO_REQ,
25 L1CTL_ECHO_CONF,
26 L1CTL_RACH_CONF,
27 L1CTL_RESET_REQ,
28 L1CTL_RESET_CONF,
29 L1CTL_DATA_CONF,
30 L1CTL_CCCH_MODE_REQ,
31 L1CTL_CCCH_MODE_CONF,
32 L1CTL_DM_REL_REQ,
33 L1CTL_PARAM_REQ,
34 L1CTL_DM_FREQ_REQ,
35 L1CTL_CRYPTO_REQ,
36 L1CTL_SIM_REQ,
37 L1CTL_SIM_CONF,
38 L1CTL_TCH_MODE_REQ,
39 L1CTL_TCH_MODE_CONF,
40 L1CTL_NEIGH_PM_REQ,
41 L1CTL_NEIGH_PM_IND,
42 L1CTL_TRAFFIC_REQ,
43 L1CTL_TRAFFIC_CONF,
Harald Welte00d4dac2017-07-30 00:50:32 +020044 L1CTL_TRAFFIC_IND,
Vadim Yanitskiy4e79ff52019-04-22 06:38:21 +070045 L1CTL_BURST_IND,
Harald Welte00d4dac2017-07-30 00:50:32 +020046 L1CTL_TBF_CFG_REQ,
Harald Welteb3c226e2017-07-30 17:18:01 +020047 L1CTL_TBF_CFG_CONF,
48 L1CTL_DATA_TBF_REQ,
Harald Welte3a40ec72018-03-02 20:45:04 +010049 L1CTL_DATA_TBF_CONF,
50 L1CTL_DATA_ABS_REQ
Harald Weltef6543322017-07-16 07:35:10 +020051 } with { variant "FIELDLENGTH(8)" };
52
53 type enumerated L1ctlCcchMode {
54 CCCH_MODE_NONE (0),
55 CCCH_MODE_NON_COMBINED,
56 CCCH_MODE_COMBINED
57 } with { variant "FIELDLENGTH(8)" };
58
59 type enumerated L1ctlNeighMode {
60 NEIGH_MODE_NONE (0),
61 NEIGH_MODE_PM,
62 NEIGH_MODE_SB
63 } with { variant "FIELDLENGTH(8)" };
64
Harald Welte1dcc3712017-08-01 00:05:52 +020065 type enumerated L1ctlGprsCs {
66 L1CTL_CS1 (1),
67 L1CTL_CS2,
68 L1CTL_CS3,
69 L1CTL_CS4,
70 L1CTL_MCS1,
71 L1CTL_MCS2,
72 L1CTL_MCS3,
73 L1CTL_MCS4,
74 L1CTL_MCS5,
75 L1CTL_MCS6,
76 L1CTL_MCS7,
77 L1CTL_MCS8,
78 L1CTL_MCS9
79 } with { variant "FIELDLENGTH(8)" };
80
Harald Weltef6543322017-07-16 07:35:10 +020081 type enumerated L1ctlResetType {
82 L1CTL_RES_T_BOOT (0),
83 L1CTL_RES_T_FULL,
84 L1CTL_RES_T_SCHED
85 } with { variant "FIELDLENGTH(8)" };
86
Harald Weltef6543322017-07-16 07:35:10 +020087 type record L1ctlHdrFlags {
88 BIT7 padding,
89 boolean f_done
90 } with { variant "" };
91
92 type record L1ctlHeader {
93 L1ctlMsgType msg_type,
94 L1ctlHdrFlags flags,
95 OCT2 padding
96 } with { variant "" };
97
Harald Weltef8df4cb2018-03-10 15:15:08 +010098 template L1ctlHeader tr_L1ctlHeader(template L1ctlMsgType msg_type) := {
99 msg_type := msg_type,
100 flags := ?,
101 padding := ?
102 };
103
104 template (value) L1ctlHeader ts_L1ctlHeader(L1ctlMsgType msg_type) := {
Harald Welte52c713c2017-07-16 15:44:44 +0200105 msg_type := msg_type,
106 flags := { padding := '0000000'B, f_done := false },
107 padding := '0000'O
108 };
109
Harald Weltef6543322017-07-16 07:35:10 +0200110 type record L1ctlDlInfo {
Harald Welte8e4db2c2017-07-16 18:54:55 +0200111 RslChannelNr chan_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200112 RslLinkId link_id,
113 Arfcn arfcn,
Harald Welte5f0d5c82017-07-16 18:56:01 +0200114 uint32_t frame_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200115 GsmRxLev rx_level,
116 uint8_t snr,
117 uint8_t num_biterr,
118 uint8_t fire_crc
119 } with { variant "" };
120
121 type record L1ctlFbsbConf {
122 int16_t initial_freq_err,
123 uint8_t result,
124 uint8_t bsic
125 } with { variant "" };
126
127 type record L1ctlCcchModeConf {
128 L1ctlCcchMode ccch_mode,
129 OCT3 padding
130 } with { variant "" };
131
132 /* gsm48_chan_mode */
133 type uint8_t L1ctlTchMode;
134
135 type record L1ctlAudioMode {
136 BIT4 padding,
137 boolean tx_microphone,
138 boolean tx_traffic_req,
139 boolean rx_speaker,
140 boolean rx_traffic_ind
141 } with { variant "" };
142
Harald Weltef8df4cb2018-03-10 15:15:08 +0100143 template (value) L1ctlAudioMode t_L1CTL_AudioModeNone := { '0000'B, false, false, false, false };
Harald Welte66110f02017-07-16 21:05:18 +0200144
Harald Weltef6543322017-07-16 07:35:10 +0200145 type record L1ctlTchModeConf {
146 L1ctlTchMode tch_mode,
147 L1ctlAudioMode audio_mode,
148 OCT2 padding
149 } with { variant "" };
150
151 type record L1ctlDataInd {
152 octetstring payload length(23)
Harald Welte7024baa2018-03-02 23:37:51 +0100153 } with {
154 variant (payload) "BYTEORDER(first)"
155 };
Harald Weltef6543322017-07-16 07:35:10 +0200156
157 type union L1ctlDlPayload {
158 L1ctlFbsbConf fbsb_conf,
159 L1ctlCcchModeConf ccch_mode_conf,
160 L1ctlTchModeConf tch_mode_conf,
161 L1ctlDataInd data_ind,
162 L1ctlTrafficReq traffic_ind,
Harald Welte00d4dac2017-07-30 00:50:32 +0200163 L1ctlTbfCfgReq tbf_cfg_conf,
Harald Weltef6543322017-07-16 07:35:10 +0200164 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100165 } with {
166 variant (other) "BYTEORDER(first)"
167 };
Harald Weltef6543322017-07-16 07:35:10 +0200168
169 type record L1ctlDlMessage {
170 L1ctlHeader header,
171 L1ctlDlInfo dl_info optional,
Harald Weltef56cc492018-04-15 10:58:43 +0200172 L1ctlDlPayload payload optional
Harald Weltef6543322017-07-16 07:35:10 +0200173 } with { variant (dl_info) "PRESENCE(header.msg_type = L1CTL_FBSB_CONF,
174 header.msg_type = L1CTL_RACH_CONF,
175 header.msg_type = L1CTL_DATA_IND,
176 header.msg_type = L1CTL_DATA_CONF,
Harald Welte3c4cbf62018-03-30 10:31:39 +0200177 header.msg_type = L1CTL_TRAFFIC_IND,
178 header.msg_type = L1CTL_TRAFFIC_CONF)"
Harald Weltef6543322017-07-16 07:35:10 +0200179 variant (payload) "CROSSTAG(fbsb_conf, header.msg_type = L1CTL_FBSB_CONF;
180 ccch_mode_conf, header.msg_type = L1CTL_CCCH_MODE_CONF;
181 tch_mode_conf, header.msg_type = L1CTL_TCH_MODE_CONF;
182 data_ind, header.msg_type = L1CTL_DATA_IND;
183 traffic_ind, header.msg_type = L1CTL_TRAFFIC_IND;
Harald Welte00d4dac2017-07-30 00:50:32 +0200184 tbf_cfg_conf, header.msg_type = L1CTL_TBF_CFG_CONF;
Harald Weltef6543322017-07-16 07:35:10 +0200185 other, OTHERWISE;
186 )" };
187
188 external function enc_L1ctlDlMessage(in L1ctlDlMessage msg) return octetstring
189 with { extension "prototype(convert) encode(RAW)" };
190 external function dec_L1ctlDlMessage(in octetstring stream) return L1ctlDlMessage
191 with { extension "prototype(convert) decode(RAW)" };
192
193
194 type record L1ctlUlInfo {
Harald Welte8e4db2c2017-07-16 18:54:55 +0200195 RslChannelNr chan_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200196 RslLinkId link_id,
197 OCT2 padding
198 } with { variant "" };
199
Harald Welteb3c226e2017-07-30 17:18:01 +0200200 type record L1ctlUlTbfInfo {
201 uint8_t tbf_nr,
Harald Welte1dcc3712017-08-01 00:05:52 +0200202 L1ctlGprsCs cs,
203 OCT2 padding
Harald Welteb3c226e2017-07-30 17:18:01 +0200204 } with { variant "" };
205
Harald Welte3a40ec72018-03-02 20:45:04 +0100206 type record L1ctlUlAbsInfo {
207 uint8_t tbf_nr,
208 L1ctlGprsCs cs,
209 uint8_t ts_nr,
210 OCT1 padding,
Harald Welte7024baa2018-03-02 23:37:51 +0100211 uint32_le fn,
Harald Welte3a40ec72018-03-02 20:45:04 +0100212 Arfcn arfcn,
213 OCT2 padding2
214 } with { variant "" };
215
Harald Weltef6543322017-07-16 07:35:10 +0200216 type record L1ctlFbsbFlags {
217 BIT5 padding,
218 boolean sb,
219 boolean fb1,
220 boolean fb0
Harald Welte344c0cf2018-03-09 16:17:45 +0100221 } with { variant "FIELDORDER(msb)" };
Harald Weltef6543322017-07-16 07:35:10 +0200222
Harald Weltef8df4cb2018-03-10 15:15:08 +0100223 template (value) L1ctlFbsbFlags t_L1CTL_FBSB_F_ALL := {
Harald Welte66110f02017-07-16 21:05:18 +0200224 padding := '00000'B,
225 sb := true,
226 fb1 := true,
227 fb0 := true
228 };
229
Harald Weltef6543322017-07-16 07:35:10 +0200230 type record L1ctlFbsbReq {
231 Arfcn arfcn,
232 uint16_t timeout_tdma_frames,
233 uint16_t freq_err_thresh1,
234 uint16_t freq_err_thresh2,
235 uint8_t num_freqerr_avg,
236 L1ctlFbsbFlags flags,
237 uint8_t sync_info_idx,
238 L1ctlCcchMode ccch_mode,
239 GsmRxLev rxlev_exp
240 } with { variant "" };
241
242 type record L1ctlCcchModeReq {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100243 L1ctlCcchMode ccch_mode,
244 OCT3 padding
Harald Weltef6543322017-07-16 07:35:10 +0200245 } with { variant "" };
246
247 type record L1ctlTchModeReq {
248 L1ctlTchMode tch_mode,
249 L1ctlAudioMode audio_mode,
250 OCT2 padding
251 } with { variant "" };
252
253 type record L1ctlRachReq {
254 uint8_t ra,
255 uint8_t combined,
256 uint16_t offset
257 } with { variant "" };
258
259 type record L1ctlParReq {
260 int8_t ta,
261 uint8_t tx_power,
262 OCT2 padding
263 } with { variant "" };
264
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200265 type record L1ctlDataReq {
266 SacchL1Header l1header optional,
267 octetstring l2_payload
268 } with { variant "" };
269
Harald Weltef6543322017-07-16 07:35:10 +0200270 type record L1ctlH1 {
271 uint8_t hsn,
272 uint8_t maio,
273 uint8_t n,
274 OCT1 padding,
275 bitstring ma length(64)
276 } with { variant "" };
277
278 type record L1ctlDmEstReq {
279 GsmTsc tsc,
280 uint8_t h,
281 Arfcn arfcn optional,
282 L1ctlH1 hopping optional,
283 L1ctlTchMode tch_mode,
284 L1ctlAudioMode audio_mode
285 } with { variant (arfcn) "PRESENCE(h = 0)"
286 variant (hopping) "PRESENCE(h = 1)" };
287
288 type record L1ctlReset {
289 L1ctlResetType reset_type,
290 OCT3 padding
291 } with { variant "" };
292
Harald Weltee613f962018-04-18 22:38:16 +0200293 type record L1CtlCryptoReq {
294 uint8_t algo,
295 uint8_t key_len,
296 octetstring key
297 } with { variant (key_len) "LENGTHTO(key)" };
298
Harald Weltef6543322017-07-16 07:35:10 +0200299
300 type record L1ctlTrafficReq {
Vadim Yanitskiye01691d2018-10-29 00:18:04 +0700301 octetstring data
Harald Welte7024baa2018-03-02 23:37:51 +0100302 } with {
303 variant (data) "BYTEORDER(first)"
304 }
Harald Weltef6543322017-07-16 07:35:10 +0200305
Harald Welte00d4dac2017-07-30 00:50:32 +0200306 type record length(8) of uint8_t TfiUsfArr;
307
308 type record L1ctlTbfCfgReq {
309 uint8_t tbf_nr,
310 boolean is_uplink,
311 OCT2 padding,
312 TfiUsfArr tfi_usf
313 } with { variant (is_uplink) "FIELDLENGTH(8)" };
314
Harald Weltef6543322017-07-16 07:35:10 +0200315 type union L1ctlUlPayload {
316 L1ctlFbsbReq fbsb_req,
317 L1ctlCcchModeReq ccch_mode_req,
318 L1ctlTchModeReq tch_mode_req,
319 L1ctlRachReq rach_req,
320 L1ctlParReq par_req,
321 L1ctlDmEstReq dm_est_req,
322 L1ctlReset reset_req,
323 //L1ctlNeighPmReq neigh_pm_req,
Harald Weltee613f962018-04-18 22:38:16 +0200324 L1CtlCryptoReq crypto_req,
Harald Weltef6543322017-07-16 07:35:10 +0200325 L1ctlTrafficReq traffic_req,
Harald Welte00d4dac2017-07-30 00:50:32 +0200326 L1ctlTbfCfgReq tbf_cfg_req,
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200327 L1ctlDataReq data_req,
Harald Weltef6543322017-07-16 07:35:10 +0200328 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100329 } with {
330 variant (other) "BYTEORDER(first)"
331 };
Harald Weltef6543322017-07-16 07:35:10 +0200332
333 type record L1ctlUlMessage {
334 L1ctlHeader header,
335 L1ctlUlInfo ul_info optional,
Harald Welteb3c226e2017-07-30 17:18:01 +0200336 L1ctlUlTbfInfo ul_info_tbf optional,
Harald Welte3a40ec72018-03-02 20:45:04 +0100337 L1ctlUlAbsInfo ul_info_abs optional,
Harald Weltef6543322017-07-16 07:35:10 +0200338 L1ctlUlPayload payload
339 } with { variant (ul_info) "PRESENCE(header.msg_type = L1CTL_RACH_REQ,
340 header.msg_type = L1CTL_PARAM_REQ,
341 header.msg_type = L1CTL_CRYPTO_REQ,
342 header.msg_type = L1CTL_DATA_REQ,
343 header.msg_type = L1CTL_DM_EST_REQ,
344 header.msg_type = L1CTL_DM_FREQ_REQ,
345 header.msg_type = L1CTL_DM_REL_REQ,
346 header.msg_type = L1CTL_TRAFFIC_REQ)"
Harald Welteb3c226e2017-07-30 17:18:01 +0200347 variant (ul_info_tbf) "PRESENCE(header.msg_type = L1CTL_DATA_TBF_REQ)"
Harald Welte3a40ec72018-03-02 20:45:04 +0100348 variant (ul_info_abs) "PRESENCE(header.msg_type = L1CTL_DATA_ABS_REQ)"
Harald Weltef6543322017-07-16 07:35:10 +0200349 variant (payload) "CROSSTAG(fbsb_req, header.msg_type = L1CTL_FBSB_REQ;
350 ccch_mode_req, header.msg_type = L1CTL_CCCH_MODE_REQ;
351 tch_mode_req, header.msg_type = L1CTL_TCH_MODE_REQ;
352 rach_req, header.msg_type = L1CTL_RACH_REQ;
353 par_req, header.msg_type = L1CTL_PARAM_REQ;
354 dm_est_req, header.msg_type = L1CTL_DM_EST_REQ;
355 reset_req, header.msg_type = L1CTL_RESET_REQ;
Harald Weltee613f962018-04-18 22:38:16 +0200356 crypto_req, header.msg_type = L1CTL_CRYPTO_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200357 traffic_req, header.msg_type = L1CTL_TRAFFIC_REQ;
Harald Welte00d4dac2017-07-30 00:50:32 +0200358 tbf_cfg_req, header.msg_type = L1CTL_TBF_CFG_REQ;
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200359 data_req, header.msg_type = L1CTL_DATA_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200360 other, OTHERWISE;
361 )" };
362
363 external function enc_L1ctlUlMessage(in L1ctlUlMessage msg) return octetstring
364 with { extension "prototype(convert) encode(RAW)" };
365 external function dec_L1ctlUlMessage(in octetstring stream) return L1ctlUlMessage
366 with { extension "prototype(convert) decode(RAW)" };
367
Harald Welte52c713c2017-07-16 15:44:44 +0200368 type record L1ctlUlMessageLV {
369 uint16_t len,
370 L1ctlUlMessage msg
371 } with { variant (len) "LENGTHTO(msg)" };
372
373 external function enc_L1ctlUlMessageLV(in L1ctlUlMessageLV msg) return octetstring
374 with { extension "prototype(convert) encode(RAW)" };
375 external function dec_L1ctlUlMessageLV(in octetstring stream) return L1ctlUlMessageLV
376 with { extension "prototype(convert) decode(RAW)" };
377
378 type record L1ctlDlMessageLV {
379 uint16_t len,
380 L1ctlDlMessage msg
381 } with { variant (len) "LENGTHTO(msg)" };
382
383 external function enc_L1ctlDlMessageLV(in L1ctlDlMessageLV msg) return octetstring
384 with { extension "prototype(convert) encode(RAW)" };
385 external function dec_L1ctlDlMessageLV(in octetstring stream) return L1ctlDlMessageLV
386 with { extension "prototype(convert) decode(RAW)" };
387
388
Harald Welte9e4725d2017-07-16 23:18:09 +0200389
390
391 /* for generating RESET_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100392 template (value) L1ctlUlMessage t_L1ctlResetReq(L1ctlResetType rst_type) := {
393 header := ts_L1ctlHeader(L1CTL_RESET_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200394 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200395 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100396 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200397 payload := {
398 reset_req := {
399 reset_type := rst_type,
400 padding := '000000'O
401 }
402 }
403 };
404
405 /* for generating FBSB_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100406 template (value) L1ctlUlMessage ts_L1CTL_FBSB_REQ(Arfcn arfcn, L1ctlFbsbFlags flags,
407 uint8_t sync_info_idx,
408 L1ctlCcchMode ccch_mode,
409 GsmRxLev rxlev_exp) := {
410 header := ts_L1ctlHeader(L1CTL_FBSB_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200411 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200412 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100413 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200414 payload := {
415 fbsb_req := {
416 arfcn := arfcn,
Harald Weltea82f7e62018-02-22 18:51:33 +0100417 timeout_tdma_frames := 250, /* about 1s */
Harald Welte9e4725d2017-07-16 23:18:09 +0200418 freq_err_thresh1 := 10000,
419 freq_err_thresh2 := 800,
420 num_freqerr_avg := 3,
421 flags := flags,
422 sync_info_idx := sync_info_idx,
423 ccch_mode := ccch_mode,
424 rxlev_exp := rxlev_exp
425 }
426 }
427 };
428
429 /* for matching against incoming FBSB_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100430 template L1ctlDlMessage tr_L1CTL_FBSB_CONF(template uint8_t result) := {
431 header := tr_L1ctlHeader(L1CTL_FBSB_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200432 dl_info := ?,
433 payload := {
434 fbsb_conf := {
435 initial_freq_err := ?,
436 result := result,
437 bsic := ?
438 }
439 }
440 };
441
Harald Weltef8df4cb2018-03-10 15:15:08 +0100442 template (value) L1ctlUlMessage ts_L1CTL_CCCH_MODE_REQ(L1ctlCcchMode ccch_mode) := {
443 header := ts_L1ctlHeader(L1CTL_CCCH_MODE_REQ),
444 ul_info := omit,
445 ul_info_tbf := omit,
446 ul_info_abs := omit,
447 payload := {
448 ccch_mode_req := {
449 ccch_mode := ccch_mode,
450 padding := '000000'O
451 }
452 }
453 };
454
Harald Welte3757e602018-03-10 17:12:02 +0100455
456 template L1ctlDlMessage tr_L1CTL_MsgType(template L1ctlMsgType msg_type) := {
457 header := tr_L1ctlHeader(msg_type),
458 dl_info := *,
Harald Weltef56cc492018-04-15 10:58:43 +0200459 payload := *
Harald Welte3757e602018-03-10 17:12:02 +0100460 }
461
462 template L1ctlDlMessage tr_L1CTL_CCCH_MODE_CONF := tr_L1CTL_MsgType(L1CTL_CCCH_MODE_CONF);
Harald Weltef8df4cb2018-03-10 15:15:08 +0100463
464 template L1ctlUlMessage ts_L1CTL_RACH_REQ(uint8_t ra, uint8_t combined, uint16_t offset) := {
465 header := ts_L1ctlHeader(L1CTL_RACH_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200466 ul_info := {
467 chan_nr := t_RslChanNr_RACH(0),
468 link_id := ts_RslLinkID_DCCH(0),
469 padding := '0000'O
470 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200471 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100472 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200473 payload := {
474 rach_req := {
475 ra := ra,
476 combined := combined,
477 offset := offset
478 }
479 }
480 }
481
Harald Weltef8df4cb2018-03-10 15:15:08 +0100482 template L1ctlUlMessage ts_L1CTL_PAR_REQ(uint8_t ta, uint8_t tx_power) := {
483 header := ts_L1ctlHeader(L1CTL_PARAM_REQ),
Harald Welte37052732018-03-09 19:38:46 +0100484 ul_info := {
485 chan_nr := t_RslChanNr_RACH(0),
486 link_id := ts_RslLinkID_DCCH(0),
487 padding := '0000'O
488 },
489 ul_info_tbf := omit,
490 ul_info_abs := omit,
491 payload := {
492 par_req := {
493 ta := ta,
494 tx_power := tx_power,
495 padding := '0000'O
496 }
497 }
498 }
499
Harald Weltef8df4cb2018-03-10 15:15:08 +0100500 template L1ctlUlMessage ts_L1CTL_DM_EST_REQ(Arfcn arfcn, RslChannelNr chan_nr, GsmTsc tsc) := {
501 header := ts_L1ctlHeader(L1CTL_DM_EST_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200502 ul_info := {
503 chan_nr := chan_nr,
504 link_id := ts_RslLinkID_DCCH(0),
505 padding := '0000'O
506 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200507 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100508 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200509 payload := {
510 dm_est_req := {
511 tsc := tsc,
512 h := 0,
513 arfcn := arfcn,
514 hopping := omit,
515 tch_mode := 0,
516 audio_mode := t_L1CTL_AudioModeNone
517 }
518 }
519 }
520
Harald Weltef8df4cb2018-03-10 15:15:08 +0100521 template L1ctlUlMessage ts_L1CTL_DM_REL_REQ(RslChannelNr chan_nr) := {
522 header := ts_L1ctlHeader(L1CTL_DM_REL_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200523 ul_info := {
524 chan_nr := chan_nr,
525 link_id := ts_RslLinkID_DCCH(0),
526 padding := '0000'O
527 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200528 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100529 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200530 payload := {
531 other := ''O
532 }
533 }
534
Harald Weltef8df4cb2018-03-10 15:15:08 +0100535 template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ(template (value) RslChannelNr chan_nr,
536 template (value) RslLinkId link_id,
537 octetstring l2_data) := {
538 header := ts_L1ctlHeader(L1CTL_DATA_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200539 ul_info := {
540 chan_nr := chan_nr,
541 link_id := link_id,
542 padding := '0000'O
543 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200544 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100545 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200546 payload := {
547 other := l2_data
548 }
549 }
550
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200551 template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ_SACCH(template (value) RslChannelNr chan_nr,
552 template (value) RslLinkId link_id,
553 L1ctlDataReq data_req) := {
554 header := ts_L1ctlHeader(L1CTL_DATA_REQ),
555 ul_info := {
556 chan_nr := chan_nr,
557 link_id := link_id,
558 padding := '0000'O
559 },
560 ul_info_tbf := omit,
561 ul_info_abs := omit,
562 payload := {
563 data_req := data_req
564 }
565 }
566
Harald Weltef8df4cb2018-03-10 15:15:08 +0100567 template (value) L1ctlUlMessage ts_L1CTL_TBF_CFG_REQ(boolean is_uplink, TfiUsfArr tfi_usf) := {
568 header := ts_L1ctlHeader(L1CTL_TBF_CFG_REQ),
Harald Welte00d4dac2017-07-30 00:50:32 +0200569 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200570 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100571 ul_info_abs := omit,
Harald Welte00d4dac2017-07-30 00:50:32 +0200572 payload := {
573 tbf_cfg_req := {
574 tbf_nr := 0,
575 is_uplink := is_uplink,
576 padding := '0000'O,
577 tfi_usf := tfi_usf
578 }
579 }
580 };
581
Harald Weltef8df4cb2018-03-10 15:15:08 +0100582 template L1ctlDlMessage tr_L1CTL_TBF_CFG_CONF(template boolean is_uplink) := {
583 header := tr_L1ctlHeader(L1CTL_TBF_CFG_CONF),
Harald Welte00d4dac2017-07-30 00:50:32 +0200584 dl_info := omit,
585 payload := {
586 tbf_cfg_conf := {
587 tbf_nr := 0,
588 is_uplink := is_uplink,
589 padding := ?,
590 tfi_usf := ?
591 }
592 }
593 };
594
Harald Weltef8df4cb2018-03-10 15:15:08 +0100595 template (value) L1ctlUlMessage ts_L1CTL_DATA_TBF_REQ(octetstring l2_data,
596 L1ctlGprsCs cs := L1CTL_CS1,
597 uint8_t tbf_nr := 0) := {
598 header := ts_L1ctlHeader(L1CTL_DATA_TBF_REQ),
Harald Welteb3c226e2017-07-30 17:18:01 +0200599 ul_info := omit,
600 ul_info_tbf := {
601 tbf_nr := tbf_nr,
Harald Welte1dcc3712017-08-01 00:05:52 +0200602 cs := cs,
603 padding := '0000'O
Harald Welteb3c226e2017-07-30 17:18:01 +0200604 },
Harald Welte3a40ec72018-03-02 20:45:04 +0100605 ul_info_abs := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200606 payload := {
607 other := l2_data
608 }
609 }
610
Harald Weltef8df4cb2018-03-10 15:15:08 +0100611 template (value) L1ctlUlMessage ts_L1CTL_DATA_ABS_REQ(octetstring l2_data, Arfcn arfcn,
Harald Welte3a40ec72018-03-02 20:45:04 +0100612 uint8_t ts, GsmFrameNumber fn,
613 L1ctlGprsCs cs := L1CTL_CS1,
614 uint8_t tbf_nr := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100615 header := ts_L1ctlHeader(L1CTL_DATA_ABS_REQ),
Harald Welte3a40ec72018-03-02 20:45:04 +0100616 ul_info := omit,
617 ul_info_tbf := omit,
618 ul_info_abs := {
619 tbf_nr := tbf_nr,
620 cs := cs,
621 ts_nr := ts,
622 padding := '00'O,
623 fn := fn,
624 arfcn := arfcn,
625 padding2 := '0000'O
626 },
627 payload := {
628 other := l2_data
629 }
630 }
631
632
Harald Welte9e4725d2017-07-16 23:18:09 +0200633 /* for matching against incoming RACH_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100634 template L1ctlDlMessage tr_L1CTL_RACH_CONF := {
635 header := tr_L1ctlHeader(L1CTL_RACH_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200636 dl_info := ?,
Harald Weltef56cc492018-04-15 10:58:43 +0200637 payload := *
Harald Welte9e4725d2017-07-16 23:18:09 +0200638 };
639
Harald Weltece6dc442018-02-21 22:00:21 +0100640 /* for matching against incoming DATA_IND */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100641 template L1ctlDlMessage tr_L1CTL_DATA_IND(template RslChannelNr chan_nr,
Harald Welte68e495b2018-02-25 00:05:57 +0100642 template RslLinkId link_id := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100643 template octetstring l2_data := ?,
644 template uint8_t num_biterr := 0,
645 template uint8_t fire_crc := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100646 header := tr_L1ctlHeader(L1CTL_DATA_IND),
Harald Welte9e4725d2017-07-16 23:18:09 +0200647 dl_info := {
648 chan_nr := chan_nr,
Harald Weltece6dc442018-02-21 22:00:21 +0100649 link_id := link_id,
Harald Welte9e4725d2017-07-16 23:18:09 +0200650 arfcn := ?,
651 frame_nr := ?,
652 rx_level := ?,
653 snr := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100654 num_biterr := num_biterr,
655 fire_crc := fire_crc
Harald Welte9e4725d2017-07-16 23:18:09 +0200656 },
657 payload := {
Harald Welte68e495b2018-02-25 00:05:57 +0100658 data_ind := {
659 payload := l2_data
660 }
Harald Welte9e4725d2017-07-16 23:18:09 +0200661 }
662 };
663
Harald Weltee613f962018-04-18 22:38:16 +0200664 template (value) L1ctlUlMessage ts_L1CTL_CRYPTO_REQ(RslChannelNr chan_nr, uint8_t algo,
665 octetstring key) := {
666 header := ts_L1ctlHeader(L1CTL_CRYPTO_REQ),
667 ul_info := {
668 chan_nr := chan_nr,
669 link_id := ts_RslLinkID_DCCH(0),
670 padding := '0000'O
671 },
672 ul_info_tbf := omit,
673 ul_info_abs := omit,
674 payload := {
675 crypto_req := {
676 algo := algo,
677 key_len := 0, /* overwritten */
678 key := key
679 }
680 }
681 };
682
Harald Welte88849c62017-07-30 17:19:41 +0200683 template ImmediateAssignment t_IMM_ASS(uint8_t ra, GsmFrameNumber fn) := {
684 ded_or_tbf := ?,
685 page_mode := ?,
686 chan_desc := *,
687 pkt_chan_desc := *,
688 req_ref := f_compute_ReqRef(ra, fn),
689 timing_advance := ?,
690 mobile_allocation := ?,
691 rest_octets:= ?
692 };
693
694 template GsmRrMessage t_RR_IMM_ASS(uint8_t ra, GsmFrameNumber fn) := {
Harald Welte9e4725d2017-07-16 23:18:09 +0200695 header := t_RrHeader(IMMEDIATE_ASSIGNMENT, ?),
696 payload := {
Harald Welte88849c62017-07-30 17:19:41 +0200697 imm_ass := t_IMM_ASS(ra, fn)
Harald Welte9e4725d2017-07-16 23:18:09 +0200698 }
699 };
700
Harald Welte68e495b2018-02-25 00:05:57 +0100701 const octetstring c_DummyUI := '0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O;
702
Harald Welte7024baa2018-03-02 23:37:51 +0100703/* We use "BYTEORDER(last)" so we get little-endian integers. Unfortuantely, this also
704 switches the byte ordering in octet strings, so we need to explicitly annotate them :/ */
Harald Weltef6543322017-07-16 07:35:10 +0200705} with { encode "RAW" };