blob: d883a22400be5569686fd475a26d9739067933d2 [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,
45 L1CTL_TBF_CFG_REQ,
Harald Welteb3c226e2017-07-30 17:18:01 +020046 L1CTL_TBF_CFG_CONF,
47 L1CTL_DATA_TBF_REQ,
Harald Welte3a40ec72018-03-02 20:45:04 +010048 L1CTL_DATA_TBF_CONF,
49 L1CTL_DATA_ABS_REQ
Harald Weltef6543322017-07-16 07:35:10 +020050 } with { variant "FIELDLENGTH(8)" };
51
52 type enumerated L1ctlCcchMode {
53 CCCH_MODE_NONE (0),
54 CCCH_MODE_NON_COMBINED,
55 CCCH_MODE_COMBINED
56 } with { variant "FIELDLENGTH(8)" };
57
58 type enumerated L1ctlNeighMode {
59 NEIGH_MODE_NONE (0),
60 NEIGH_MODE_PM,
61 NEIGH_MODE_SB
62 } with { variant "FIELDLENGTH(8)" };
63
Harald Welte1dcc3712017-08-01 00:05:52 +020064 type enumerated L1ctlGprsCs {
65 L1CTL_CS1 (1),
66 L1CTL_CS2,
67 L1CTL_CS3,
68 L1CTL_CS4,
69 L1CTL_MCS1,
70 L1CTL_MCS2,
71 L1CTL_MCS3,
72 L1CTL_MCS4,
73 L1CTL_MCS5,
74 L1CTL_MCS6,
75 L1CTL_MCS7,
76 L1CTL_MCS8,
77 L1CTL_MCS9
78 } with { variant "FIELDLENGTH(8)" };
79
Harald Weltef6543322017-07-16 07:35:10 +020080 type enumerated L1ctlResetType {
81 L1CTL_RES_T_BOOT (0),
82 L1CTL_RES_T_FULL,
83 L1CTL_RES_T_SCHED
84 } with { variant "FIELDLENGTH(8)" };
85
86 const integer TRAFFIC_DATA_LEN := 40;
87
88 type record L1ctlHdrFlags {
89 BIT7 padding,
90 boolean f_done
91 } with { variant "" };
92
93 type record L1ctlHeader {
94 L1ctlMsgType msg_type,
95 L1ctlHdrFlags flags,
96 OCT2 padding
97 } with { variant "" };
98
Harald Weltef8df4cb2018-03-10 15:15:08 +010099 template L1ctlHeader tr_L1ctlHeader(template L1ctlMsgType msg_type) := {
100 msg_type := msg_type,
101 flags := ?,
102 padding := ?
103 };
104
105 template (value) L1ctlHeader ts_L1ctlHeader(L1ctlMsgType msg_type) := {
Harald Welte52c713c2017-07-16 15:44:44 +0200106 msg_type := msg_type,
107 flags := { padding := '0000000'B, f_done := false },
108 padding := '0000'O
109 };
110
Harald Weltef6543322017-07-16 07:35:10 +0200111 type record L1ctlDlInfo {
Harald Welte8e4db2c2017-07-16 18:54:55 +0200112 RslChannelNr chan_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200113 RslLinkId link_id,
114 Arfcn arfcn,
Harald Welte5f0d5c82017-07-16 18:56:01 +0200115 uint32_t frame_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200116 GsmRxLev rx_level,
117 uint8_t snr,
118 uint8_t num_biterr,
119 uint8_t fire_crc
120 } with { variant "" };
121
122 type record L1ctlFbsbConf {
123 int16_t initial_freq_err,
124 uint8_t result,
125 uint8_t bsic
126 } with { variant "" };
127
128 type record L1ctlCcchModeConf {
129 L1ctlCcchMode ccch_mode,
130 OCT3 padding
131 } with { variant "" };
132
133 /* gsm48_chan_mode */
134 type uint8_t L1ctlTchMode;
135
136 type record L1ctlAudioMode {
137 BIT4 padding,
138 boolean tx_microphone,
139 boolean tx_traffic_req,
140 boolean rx_speaker,
141 boolean rx_traffic_ind
142 } with { variant "" };
143
Harald Weltef8df4cb2018-03-10 15:15:08 +0100144 template (value) L1ctlAudioMode t_L1CTL_AudioModeNone := { '0000'B, false, false, false, false };
Harald Welte66110f02017-07-16 21:05:18 +0200145
Harald Weltef6543322017-07-16 07:35:10 +0200146 type record L1ctlTchModeConf {
147 L1ctlTchMode tch_mode,
148 L1ctlAudioMode audio_mode,
149 OCT2 padding
150 } with { variant "" };
151
152 type record L1ctlDataInd {
153 octetstring payload length(23)
Harald Welte7024baa2018-03-02 23:37:51 +0100154 } with {
155 variant (payload) "BYTEORDER(first)"
156 };
Harald Weltef6543322017-07-16 07:35:10 +0200157
158 type union L1ctlDlPayload {
159 L1ctlFbsbConf fbsb_conf,
160 L1ctlCcchModeConf ccch_mode_conf,
161 L1ctlTchModeConf tch_mode_conf,
162 L1ctlDataInd data_ind,
163 L1ctlTrafficReq traffic_ind,
Harald Welte00d4dac2017-07-30 00:50:32 +0200164 L1ctlTbfCfgReq tbf_cfg_conf,
Harald Weltef6543322017-07-16 07:35:10 +0200165 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100166 } with {
167 variant (other) "BYTEORDER(first)"
168 };
Harald Weltef6543322017-07-16 07:35:10 +0200169
170 type record L1ctlDlMessage {
171 L1ctlHeader header,
172 L1ctlDlInfo dl_info optional,
173 L1ctlDlPayload payload
174 } with { variant (dl_info) "PRESENCE(header.msg_type = L1CTL_FBSB_CONF,
175 header.msg_type = L1CTL_RACH_CONF,
176 header.msg_type = L1CTL_DATA_IND,
177 header.msg_type = L1CTL_DATA_CONF,
178 header.msg_type = L1CTL_TRAFFIC_IND)"
179 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
265 type record L1ctlH1 {
266 uint8_t hsn,
267 uint8_t maio,
268 uint8_t n,
269 OCT1 padding,
270 bitstring ma length(64)
271 } with { variant "" };
272
273 type record L1ctlDmEstReq {
274 GsmTsc tsc,
275 uint8_t h,
276 Arfcn arfcn optional,
277 L1ctlH1 hopping optional,
278 L1ctlTchMode tch_mode,
279 L1ctlAudioMode audio_mode
280 } with { variant (arfcn) "PRESENCE(h = 0)"
281 variant (hopping) "PRESENCE(h = 1)" };
282
283 type record L1ctlReset {
284 L1ctlResetType reset_type,
285 OCT3 padding
286 } with { variant "" };
287
288
289 type record L1ctlTrafficReq {
290 octetstring data length(TRAFFIC_DATA_LEN)
Harald Welte7024baa2018-03-02 23:37:51 +0100291 } with {
292 variant (data) "BYTEORDER(first)"
293 }
Harald Weltef6543322017-07-16 07:35:10 +0200294
Harald Welte00d4dac2017-07-30 00:50:32 +0200295 type record length(8) of uint8_t TfiUsfArr;
296
297 type record L1ctlTbfCfgReq {
298 uint8_t tbf_nr,
299 boolean is_uplink,
300 OCT2 padding,
301 TfiUsfArr tfi_usf
302 } with { variant (is_uplink) "FIELDLENGTH(8)" };
303
Harald Weltef6543322017-07-16 07:35:10 +0200304 type union L1ctlUlPayload {
305 L1ctlFbsbReq fbsb_req,
306 L1ctlCcchModeReq ccch_mode_req,
307 L1ctlTchModeReq tch_mode_req,
308 L1ctlRachReq rach_req,
309 L1ctlParReq par_req,
310 L1ctlDmEstReq dm_est_req,
311 L1ctlReset reset_req,
312 //L1ctlNeighPmReq neigh_pm_req,
313 L1ctlTrafficReq traffic_req,
Harald Welte00d4dac2017-07-30 00:50:32 +0200314 L1ctlTbfCfgReq tbf_cfg_req,
Harald Weltef6543322017-07-16 07:35:10 +0200315 octetstring other
Harald Welte7024baa2018-03-02 23:37:51 +0100316 } with {
317 variant (other) "BYTEORDER(first)"
318 };
Harald Weltef6543322017-07-16 07:35:10 +0200319
320 type record L1ctlUlMessage {
321 L1ctlHeader header,
322 L1ctlUlInfo ul_info optional,
Harald Welteb3c226e2017-07-30 17:18:01 +0200323 L1ctlUlTbfInfo ul_info_tbf optional,
Harald Welte3a40ec72018-03-02 20:45:04 +0100324 L1ctlUlAbsInfo ul_info_abs optional,
Harald Weltef6543322017-07-16 07:35:10 +0200325 L1ctlUlPayload payload
326 } with { variant (ul_info) "PRESENCE(header.msg_type = L1CTL_RACH_REQ,
327 header.msg_type = L1CTL_PARAM_REQ,
328 header.msg_type = L1CTL_CRYPTO_REQ,
329 header.msg_type = L1CTL_DATA_REQ,
330 header.msg_type = L1CTL_DM_EST_REQ,
331 header.msg_type = L1CTL_DM_FREQ_REQ,
332 header.msg_type = L1CTL_DM_REL_REQ,
333 header.msg_type = L1CTL_TRAFFIC_REQ)"
Harald Welteb3c226e2017-07-30 17:18:01 +0200334 variant (ul_info_tbf) "PRESENCE(header.msg_type = L1CTL_DATA_TBF_REQ)"
Harald Welte3a40ec72018-03-02 20:45:04 +0100335 variant (ul_info_abs) "PRESENCE(header.msg_type = L1CTL_DATA_ABS_REQ)"
Harald Weltef6543322017-07-16 07:35:10 +0200336 variant (payload) "CROSSTAG(fbsb_req, header.msg_type = L1CTL_FBSB_REQ;
337 ccch_mode_req, header.msg_type = L1CTL_CCCH_MODE_REQ;
338 tch_mode_req, header.msg_type = L1CTL_TCH_MODE_REQ;
339 rach_req, header.msg_type = L1CTL_RACH_REQ;
340 par_req, header.msg_type = L1CTL_PARAM_REQ;
341 dm_est_req, header.msg_type = L1CTL_DM_EST_REQ;
342 reset_req, header.msg_type = L1CTL_RESET_REQ;
343 traffic_req, header.msg_type = L1CTL_TRAFFIC_REQ;
Harald Welte00d4dac2017-07-30 00:50:32 +0200344 tbf_cfg_req, header.msg_type = L1CTL_TBF_CFG_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200345 other, OTHERWISE;
346 )" };
347
348 external function enc_L1ctlUlMessage(in L1ctlUlMessage msg) return octetstring
349 with { extension "prototype(convert) encode(RAW)" };
350 external function dec_L1ctlUlMessage(in octetstring stream) return L1ctlUlMessage
351 with { extension "prototype(convert) decode(RAW)" };
352
Harald Welte52c713c2017-07-16 15:44:44 +0200353 type record L1ctlUlMessageLV {
354 uint16_t len,
355 L1ctlUlMessage msg
356 } with { variant (len) "LENGTHTO(msg)" };
357
358 external function enc_L1ctlUlMessageLV(in L1ctlUlMessageLV msg) return octetstring
359 with { extension "prototype(convert) encode(RAW)" };
360 external function dec_L1ctlUlMessageLV(in octetstring stream) return L1ctlUlMessageLV
361 with { extension "prototype(convert) decode(RAW)" };
362
363 type record L1ctlDlMessageLV {
364 uint16_t len,
365 L1ctlDlMessage msg
366 } with { variant (len) "LENGTHTO(msg)" };
367
368 external function enc_L1ctlDlMessageLV(in L1ctlDlMessageLV msg) return octetstring
369 with { extension "prototype(convert) encode(RAW)" };
370 external function dec_L1ctlDlMessageLV(in octetstring stream) return L1ctlDlMessageLV
371 with { extension "prototype(convert) decode(RAW)" };
372
373
Harald Welte9e4725d2017-07-16 23:18:09 +0200374
375
376 /* for generating RESET_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100377 template (value) L1ctlUlMessage t_L1ctlResetReq(L1ctlResetType rst_type) := {
378 header := ts_L1ctlHeader(L1CTL_RESET_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200379 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200380 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100381 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200382 payload := {
383 reset_req := {
384 reset_type := rst_type,
385 padding := '000000'O
386 }
387 }
388 };
389
390 /* for generating FBSB_REQ */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100391 template (value) L1ctlUlMessage ts_L1CTL_FBSB_REQ(Arfcn arfcn, L1ctlFbsbFlags flags,
392 uint8_t sync_info_idx,
393 L1ctlCcchMode ccch_mode,
394 GsmRxLev rxlev_exp) := {
395 header := ts_L1ctlHeader(L1CTL_FBSB_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200396 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200397 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100398 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200399 payload := {
400 fbsb_req := {
401 arfcn := arfcn,
Harald Weltea82f7e62018-02-22 18:51:33 +0100402 timeout_tdma_frames := 250, /* about 1s */
Harald Welte9e4725d2017-07-16 23:18:09 +0200403 freq_err_thresh1 := 10000,
404 freq_err_thresh2 := 800,
405 num_freqerr_avg := 3,
406 flags := flags,
407 sync_info_idx := sync_info_idx,
408 ccch_mode := ccch_mode,
409 rxlev_exp := rxlev_exp
410 }
411 }
412 };
413
414 /* for matching against incoming FBSB_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100415 template L1ctlDlMessage tr_L1CTL_FBSB_CONF(template uint8_t result) := {
416 header := tr_L1ctlHeader(L1CTL_FBSB_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200417 dl_info := ?,
418 payload := {
419 fbsb_conf := {
420 initial_freq_err := ?,
421 result := result,
422 bsic := ?
423 }
424 }
425 };
426
Harald Weltef8df4cb2018-03-10 15:15:08 +0100427 template (value) L1ctlUlMessage ts_L1CTL_CCCH_MODE_REQ(L1ctlCcchMode ccch_mode) := {
428 header := ts_L1ctlHeader(L1CTL_CCCH_MODE_REQ),
429 ul_info := omit,
430 ul_info_tbf := omit,
431 ul_info_abs := omit,
432 payload := {
433 ccch_mode_req := {
434 ccch_mode := ccch_mode,
435 padding := '000000'O
436 }
437 }
438 };
439
Harald Welte3757e602018-03-10 17:12:02 +0100440
441 template L1ctlDlMessage tr_L1CTL_MsgType(template L1ctlMsgType msg_type) := {
442 header := tr_L1ctlHeader(msg_type),
443 dl_info := *,
Harald Weltef8df4cb2018-03-10 15:15:08 +0100444 payload := ?
Harald Welte3757e602018-03-10 17:12:02 +0100445 }
446
447 template L1ctlDlMessage tr_L1CTL_CCCH_MODE_CONF := tr_L1CTL_MsgType(L1CTL_CCCH_MODE_CONF);
Harald Weltef8df4cb2018-03-10 15:15:08 +0100448
449 template L1ctlUlMessage ts_L1CTL_RACH_REQ(uint8_t ra, uint8_t combined, uint16_t offset) := {
450 header := ts_L1ctlHeader(L1CTL_RACH_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200451 ul_info := {
452 chan_nr := t_RslChanNr_RACH(0),
453 link_id := ts_RslLinkID_DCCH(0),
454 padding := '0000'O
455 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200456 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100457 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200458 payload := {
459 rach_req := {
460 ra := ra,
461 combined := combined,
462 offset := offset
463 }
464 }
465 }
466
Harald Weltef8df4cb2018-03-10 15:15:08 +0100467 template L1ctlUlMessage ts_L1CTL_PAR_REQ(uint8_t ta, uint8_t tx_power) := {
468 header := ts_L1ctlHeader(L1CTL_PARAM_REQ),
Harald Welte37052732018-03-09 19:38:46 +0100469 ul_info := {
470 chan_nr := t_RslChanNr_RACH(0),
471 link_id := ts_RslLinkID_DCCH(0),
472 padding := '0000'O
473 },
474 ul_info_tbf := omit,
475 ul_info_abs := omit,
476 payload := {
477 par_req := {
478 ta := ta,
479 tx_power := tx_power,
480 padding := '0000'O
481 }
482 }
483 }
484
Harald Weltef8df4cb2018-03-10 15:15:08 +0100485 template L1ctlUlMessage ts_L1CTL_DM_EST_REQ(Arfcn arfcn, RslChannelNr chan_nr, GsmTsc tsc) := {
486 header := ts_L1ctlHeader(L1CTL_DM_EST_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200487 ul_info := {
488 chan_nr := chan_nr,
489 link_id := ts_RslLinkID_DCCH(0),
490 padding := '0000'O
491 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200492 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100493 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200494 payload := {
495 dm_est_req := {
496 tsc := tsc,
497 h := 0,
498 arfcn := arfcn,
499 hopping := omit,
500 tch_mode := 0,
501 audio_mode := t_L1CTL_AudioModeNone
502 }
503 }
504 }
505
Harald Weltef8df4cb2018-03-10 15:15:08 +0100506 template L1ctlUlMessage ts_L1CTL_DM_REL_REQ(RslChannelNr chan_nr) := {
507 header := ts_L1ctlHeader(L1CTL_DM_REL_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200508 ul_info := {
509 chan_nr := chan_nr,
510 link_id := ts_RslLinkID_DCCH(0),
511 padding := '0000'O
512 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200513 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100514 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200515 payload := {
516 other := ''O
517 }
518 }
519
Harald Weltef8df4cb2018-03-10 15:15:08 +0100520 template (value) L1ctlUlMessage ts_L1CTL_DATA_REQ(template (value) RslChannelNr chan_nr,
521 template (value) RslLinkId link_id,
522 octetstring l2_data) := {
523 header := ts_L1ctlHeader(L1CTL_DATA_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200524 ul_info := {
525 chan_nr := chan_nr,
526 link_id := link_id,
527 padding := '0000'O
528 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200529 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100530 ul_info_abs := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200531 payload := {
532 other := l2_data
533 }
534 }
535
Harald Weltef8df4cb2018-03-10 15:15:08 +0100536 template (value) L1ctlUlMessage ts_L1CTL_TBF_CFG_REQ(boolean is_uplink, TfiUsfArr tfi_usf) := {
537 header := ts_L1ctlHeader(L1CTL_TBF_CFG_REQ),
Harald Welte00d4dac2017-07-30 00:50:32 +0200538 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200539 ul_info_tbf := omit,
Harald Welte3a40ec72018-03-02 20:45:04 +0100540 ul_info_abs := omit,
Harald Welte00d4dac2017-07-30 00:50:32 +0200541 payload := {
542 tbf_cfg_req := {
543 tbf_nr := 0,
544 is_uplink := is_uplink,
545 padding := '0000'O,
546 tfi_usf := tfi_usf
547 }
548 }
549 };
550
Harald Weltef8df4cb2018-03-10 15:15:08 +0100551 template L1ctlDlMessage tr_L1CTL_TBF_CFG_CONF(template boolean is_uplink) := {
552 header := tr_L1ctlHeader(L1CTL_TBF_CFG_CONF),
Harald Welte00d4dac2017-07-30 00:50:32 +0200553 dl_info := omit,
554 payload := {
555 tbf_cfg_conf := {
556 tbf_nr := 0,
557 is_uplink := is_uplink,
558 padding := ?,
559 tfi_usf := ?
560 }
561 }
562 };
563
Harald Weltef8df4cb2018-03-10 15:15:08 +0100564 template (value) L1ctlUlMessage ts_L1CTL_DATA_TBF_REQ(octetstring l2_data,
565 L1ctlGprsCs cs := L1CTL_CS1,
566 uint8_t tbf_nr := 0) := {
567 header := ts_L1ctlHeader(L1CTL_DATA_TBF_REQ),
Harald Welteb3c226e2017-07-30 17:18:01 +0200568 ul_info := omit,
569 ul_info_tbf := {
570 tbf_nr := tbf_nr,
Harald Welte1dcc3712017-08-01 00:05:52 +0200571 cs := cs,
572 padding := '0000'O
Harald Welteb3c226e2017-07-30 17:18:01 +0200573 },
Harald Welte3a40ec72018-03-02 20:45:04 +0100574 ul_info_abs := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200575 payload := {
576 other := l2_data
577 }
578 }
579
Harald Weltef8df4cb2018-03-10 15:15:08 +0100580 template (value) L1ctlUlMessage ts_L1CTL_DATA_ABS_REQ(octetstring l2_data, Arfcn arfcn,
Harald Welte3a40ec72018-03-02 20:45:04 +0100581 uint8_t ts, GsmFrameNumber fn,
582 L1ctlGprsCs cs := L1CTL_CS1,
583 uint8_t tbf_nr := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100584 header := ts_L1ctlHeader(L1CTL_DATA_ABS_REQ),
Harald Welte3a40ec72018-03-02 20:45:04 +0100585 ul_info := omit,
586 ul_info_tbf := omit,
587 ul_info_abs := {
588 tbf_nr := tbf_nr,
589 cs := cs,
590 ts_nr := ts,
591 padding := '00'O,
592 fn := fn,
593 arfcn := arfcn,
594 padding2 := '0000'O
595 },
596 payload := {
597 other := l2_data
598 }
599 }
600
601
Harald Welte9e4725d2017-07-16 23:18:09 +0200602 /* for matching against incoming RACH_CONF */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100603 template L1ctlDlMessage tr_L1CTL_RACH_CONF := {
604 header := tr_L1ctlHeader(L1CTL_RACH_CONF),
Harald Welte9e4725d2017-07-16 23:18:09 +0200605 dl_info := ?,
606 payload := ?
607 };
608
Harald Weltece6dc442018-02-21 22:00:21 +0100609 /* for matching against incoming DATA_IND */
Harald Weltef8df4cb2018-03-10 15:15:08 +0100610 template L1ctlDlMessage tr_L1CTL_DATA_IND(template RslChannelNr chan_nr,
Harald Welte68e495b2018-02-25 00:05:57 +0100611 template RslLinkId link_id := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100612 template octetstring l2_data := ?,
613 template uint8_t num_biterr := 0,
614 template uint8_t fire_crc := 0) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100615 header := tr_L1ctlHeader(L1CTL_DATA_IND),
Harald Welte9e4725d2017-07-16 23:18:09 +0200616 dl_info := {
617 chan_nr := chan_nr,
Harald Weltece6dc442018-02-21 22:00:21 +0100618 link_id := link_id,
Harald Welte9e4725d2017-07-16 23:18:09 +0200619 arfcn := ?,
620 frame_nr := ?,
621 rx_level := ?,
622 snr := ?,
Harald Welte629cc6b2018-03-11 17:19:05 +0100623 num_biterr := num_biterr,
624 fire_crc := fire_crc
Harald Welte9e4725d2017-07-16 23:18:09 +0200625 },
626 payload := {
Harald Welte68e495b2018-02-25 00:05:57 +0100627 data_ind := {
628 payload := l2_data
629 }
Harald Welte9e4725d2017-07-16 23:18:09 +0200630 }
631 };
632
Harald Welte88849c62017-07-30 17:19:41 +0200633 template ImmediateAssignment t_IMM_ASS(uint8_t ra, GsmFrameNumber fn) := {
634 ded_or_tbf := ?,
635 page_mode := ?,
636 chan_desc := *,
637 pkt_chan_desc := *,
638 req_ref := f_compute_ReqRef(ra, fn),
639 timing_advance := ?,
640 mobile_allocation := ?,
641 rest_octets:= ?
642 };
643
644 template GsmRrMessage t_RR_IMM_ASS(uint8_t ra, GsmFrameNumber fn) := {
Harald Welte9e4725d2017-07-16 23:18:09 +0200645 header := t_RrHeader(IMMEDIATE_ASSIGNMENT, ?),
646 payload := {
Harald Welte88849c62017-07-30 17:19:41 +0200647 imm_ass := t_IMM_ASS(ra, fn)
Harald Welte9e4725d2017-07-16 23:18:09 +0200648 }
649 };
650
Harald Welte68e495b2018-02-25 00:05:57 +0100651 const octetstring c_DummyUI := '0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O;
652
Harald Welte7024baa2018-03-02 23:37:51 +0100653/* We use "BYTEORDER(last)" so we get little-endian integers. Unfortuantely, this also
654 switches the byte ordering in octet strings, so we need to explicitly annotate them :/ */
Harald Weltef6543322017-07-16 07:35:10 +0200655} with { encode "RAW" };