blob: 4b68c6133688ef9c3e85a394fe88bc3dc2429ac3 [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
11 type enumerated L1ctlMsgType {
12 L1CTL_NONE,
13 L1CTL_FBSB_REQ,
14 L1CTL_FBSB_CONF,
15 L1CTL_DATA_IND,
16 L1CTL_RACH_REQ,
17 L1CTL_DM_EST_REQ,
18 L1CTL_DATA_REQ,
19 L1CTL_RESET_IND,
20 L1CTL_PM_REQ, /* power measurement */
21 L1CTL_PM_CONF, /* power measurement */
22 L1CTL_ECHO_REQ,
23 L1CTL_ECHO_CONF,
24 L1CTL_RACH_CONF,
25 L1CTL_RESET_REQ,
26 L1CTL_RESET_CONF,
27 L1CTL_DATA_CONF,
28 L1CTL_CCCH_MODE_REQ,
29 L1CTL_CCCH_MODE_CONF,
30 L1CTL_DM_REL_REQ,
31 L1CTL_PARAM_REQ,
32 L1CTL_DM_FREQ_REQ,
33 L1CTL_CRYPTO_REQ,
34 L1CTL_SIM_REQ,
35 L1CTL_SIM_CONF,
36 L1CTL_TCH_MODE_REQ,
37 L1CTL_TCH_MODE_CONF,
38 L1CTL_NEIGH_PM_REQ,
39 L1CTL_NEIGH_PM_IND,
40 L1CTL_TRAFFIC_REQ,
41 L1CTL_TRAFFIC_CONF,
Harald Welte00d4dac2017-07-30 00:50:32 +020042 L1CTL_TRAFFIC_IND,
43 L1CTL_TBF_CFG_REQ,
Harald Welteb3c226e2017-07-30 17:18:01 +020044 L1CTL_TBF_CFG_CONF,
45 L1CTL_DATA_TBF_REQ,
46 L1CTL_DATA_TBF_CONF
Harald Weltef6543322017-07-16 07:35:10 +020047 } with { variant "FIELDLENGTH(8)" };
48
49 type enumerated L1ctlCcchMode {
50 CCCH_MODE_NONE (0),
51 CCCH_MODE_NON_COMBINED,
52 CCCH_MODE_COMBINED
53 } with { variant "FIELDLENGTH(8)" };
54
55 type enumerated L1ctlNeighMode {
56 NEIGH_MODE_NONE (0),
57 NEIGH_MODE_PM,
58 NEIGH_MODE_SB
59 } with { variant "FIELDLENGTH(8)" };
60
61 type enumerated L1ctlResetType {
62 L1CTL_RES_T_BOOT (0),
63 L1CTL_RES_T_FULL,
64 L1CTL_RES_T_SCHED
65 } with { variant "FIELDLENGTH(8)" };
66
67 const integer TRAFFIC_DATA_LEN := 40;
68
69 type record L1ctlHdrFlags {
70 BIT7 padding,
71 boolean f_done
72 } with { variant "" };
73
74 type record L1ctlHeader {
75 L1ctlMsgType msg_type,
76 L1ctlHdrFlags flags,
77 OCT2 padding
78 } with { variant "" };
79
Harald Welte52c713c2017-07-16 15:44:44 +020080 template L1ctlHeader t_L1ctlHeader(template L1ctlMsgType msg_type) := {
81 msg_type := msg_type,
82 flags := { padding := '0000000'B, f_done := false },
83 padding := '0000'O
84 };
85
Harald Weltef6543322017-07-16 07:35:10 +020086 type record L1ctlDlInfo {
Harald Welte8e4db2c2017-07-16 18:54:55 +020087 RslChannelNr chan_nr,
Harald Weltef6543322017-07-16 07:35:10 +020088 RslLinkId link_id,
89 Arfcn arfcn,
Harald Welte5f0d5c82017-07-16 18:56:01 +020090 uint32_t frame_nr,
Harald Weltef6543322017-07-16 07:35:10 +020091 GsmRxLev rx_level,
92 uint8_t snr,
93 uint8_t num_biterr,
94 uint8_t fire_crc
95 } with { variant "" };
96
97 type record L1ctlFbsbConf {
98 int16_t initial_freq_err,
99 uint8_t result,
100 uint8_t bsic
101 } with { variant "" };
102
103 type record L1ctlCcchModeConf {
104 L1ctlCcchMode ccch_mode,
105 OCT3 padding
106 } with { variant "" };
107
108 /* gsm48_chan_mode */
109 type uint8_t L1ctlTchMode;
110
111 type record L1ctlAudioMode {
112 BIT4 padding,
113 boolean tx_microphone,
114 boolean tx_traffic_req,
115 boolean rx_speaker,
116 boolean rx_traffic_ind
117 } with { variant "" };
118
Harald Welte66110f02017-07-16 21:05:18 +0200119 template L1ctlAudioMode t_L1CTL_AudioModeNone := { '0000'B, false, false, false, false };
120
Harald Weltef6543322017-07-16 07:35:10 +0200121 type record L1ctlTchModeConf {
122 L1ctlTchMode tch_mode,
123 L1ctlAudioMode audio_mode,
124 OCT2 padding
125 } with { variant "" };
126
127 type record L1ctlDataInd {
128 octetstring payload length(23)
129 } with { variant "" };
130
131 type union L1ctlDlPayload {
132 L1ctlFbsbConf fbsb_conf,
133 L1ctlCcchModeConf ccch_mode_conf,
134 L1ctlTchModeConf tch_mode_conf,
135 L1ctlDataInd data_ind,
136 L1ctlTrafficReq traffic_ind,
Harald Welte00d4dac2017-07-30 00:50:32 +0200137 L1ctlTbfCfgReq tbf_cfg_conf,
Harald Weltef6543322017-07-16 07:35:10 +0200138 octetstring other
139 } with { variant "" };
140
141 type record L1ctlDlMessage {
142 L1ctlHeader header,
143 L1ctlDlInfo dl_info optional,
144 L1ctlDlPayload payload
145 } with { variant (dl_info) "PRESENCE(header.msg_type = L1CTL_FBSB_CONF,
146 header.msg_type = L1CTL_RACH_CONF,
147 header.msg_type = L1CTL_DATA_IND,
148 header.msg_type = L1CTL_DATA_CONF,
149 header.msg_type = L1CTL_TRAFFIC_IND)"
150 variant (payload) "CROSSTAG(fbsb_conf, header.msg_type = L1CTL_FBSB_CONF;
151 ccch_mode_conf, header.msg_type = L1CTL_CCCH_MODE_CONF;
152 tch_mode_conf, header.msg_type = L1CTL_TCH_MODE_CONF;
153 data_ind, header.msg_type = L1CTL_DATA_IND;
154 traffic_ind, header.msg_type = L1CTL_TRAFFIC_IND;
Harald Welte00d4dac2017-07-30 00:50:32 +0200155 tbf_cfg_conf, header.msg_type = L1CTL_TBF_CFG_CONF;
Harald Weltef6543322017-07-16 07:35:10 +0200156 other, OTHERWISE;
157 )" };
158
159 external function enc_L1ctlDlMessage(in L1ctlDlMessage msg) return octetstring
160 with { extension "prototype(convert) encode(RAW)" };
161 external function dec_L1ctlDlMessage(in octetstring stream) return L1ctlDlMessage
162 with { extension "prototype(convert) decode(RAW)" };
163
164
165 type record L1ctlUlInfo {
Harald Welte8e4db2c2017-07-16 18:54:55 +0200166 RslChannelNr chan_nr,
Harald Weltef6543322017-07-16 07:35:10 +0200167 RslLinkId link_id,
168 OCT2 padding
169 } with { variant "" };
170
Harald Welteb3c226e2017-07-30 17:18:01 +0200171 type record L1ctlUlTbfInfo {
172 uint8_t tbf_nr,
173 OCT3 padding
174 } with { variant "" };
175
Harald Weltef6543322017-07-16 07:35:10 +0200176 type record L1ctlFbsbFlags {
177 BIT5 padding,
178 boolean sb,
179 boolean fb1,
180 boolean fb0
181 } with { variant "" };
182
Harald Welte66110f02017-07-16 21:05:18 +0200183 template L1ctlFbsbFlags t_L1CTL_FBSB_F_ALL := {
184 padding := '00000'B,
185 sb := true,
186 fb1 := true,
187 fb0 := true
188 };
189
Harald Weltef6543322017-07-16 07:35:10 +0200190 type record L1ctlFbsbReq {
191 Arfcn arfcn,
192 uint16_t timeout_tdma_frames,
193 uint16_t freq_err_thresh1,
194 uint16_t freq_err_thresh2,
195 uint8_t num_freqerr_avg,
196 L1ctlFbsbFlags flags,
197 uint8_t sync_info_idx,
198 L1ctlCcchMode ccch_mode,
199 GsmRxLev rxlev_exp
200 } with { variant "" };
201
202 type record L1ctlCcchModeReq {
203 L1ctlTchMode tch_mode,
204 L1ctlAudioMode audio_mode,
205 OCT2 padding
206 } with { variant "" };
207
208 type record L1ctlTchModeReq {
209 L1ctlTchMode tch_mode,
210 L1ctlAudioMode audio_mode,
211 OCT2 padding
212 } with { variant "" };
213
214 type record L1ctlRachReq {
215 uint8_t ra,
216 uint8_t combined,
217 uint16_t offset
218 } with { variant "" };
219
220 type record L1ctlParReq {
221 int8_t ta,
222 uint8_t tx_power,
223 OCT2 padding
224 } with { variant "" };
225
226 type record L1ctlH1 {
227 uint8_t hsn,
228 uint8_t maio,
229 uint8_t n,
230 OCT1 padding,
231 bitstring ma length(64)
232 } with { variant "" };
233
234 type record L1ctlDmEstReq {
235 GsmTsc tsc,
236 uint8_t h,
237 Arfcn arfcn optional,
238 L1ctlH1 hopping optional,
239 L1ctlTchMode tch_mode,
240 L1ctlAudioMode audio_mode
241 } with { variant (arfcn) "PRESENCE(h = 0)"
242 variant (hopping) "PRESENCE(h = 1)" };
243
244 type record L1ctlReset {
245 L1ctlResetType reset_type,
246 OCT3 padding
247 } with { variant "" };
248
249
250 type record L1ctlTrafficReq {
251 octetstring data length(TRAFFIC_DATA_LEN)
252 } with { variant "" };
253
Harald Welte00d4dac2017-07-30 00:50:32 +0200254 type record length(8) of uint8_t TfiUsfArr;
255
256 type record L1ctlTbfCfgReq {
257 uint8_t tbf_nr,
258 boolean is_uplink,
259 OCT2 padding,
260 TfiUsfArr tfi_usf
261 } with { variant (is_uplink) "FIELDLENGTH(8)" };
262
Harald Weltef6543322017-07-16 07:35:10 +0200263 type union L1ctlUlPayload {
264 L1ctlFbsbReq fbsb_req,
265 L1ctlCcchModeReq ccch_mode_req,
266 L1ctlTchModeReq tch_mode_req,
267 L1ctlRachReq rach_req,
268 L1ctlParReq par_req,
269 L1ctlDmEstReq dm_est_req,
270 L1ctlReset reset_req,
271 //L1ctlNeighPmReq neigh_pm_req,
272 L1ctlTrafficReq traffic_req,
Harald Welte00d4dac2017-07-30 00:50:32 +0200273 L1ctlTbfCfgReq tbf_cfg_req,
Harald Weltef6543322017-07-16 07:35:10 +0200274 octetstring other
275 } with { variant "" };
276
277 type record L1ctlUlMessage {
278 L1ctlHeader header,
279 L1ctlUlInfo ul_info optional,
Harald Welteb3c226e2017-07-30 17:18:01 +0200280 L1ctlUlTbfInfo ul_info_tbf optional,
Harald Weltef6543322017-07-16 07:35:10 +0200281 L1ctlUlPayload payload
282 } with { variant (ul_info) "PRESENCE(header.msg_type = L1CTL_RACH_REQ,
283 header.msg_type = L1CTL_PARAM_REQ,
284 header.msg_type = L1CTL_CRYPTO_REQ,
285 header.msg_type = L1CTL_DATA_REQ,
286 header.msg_type = L1CTL_DM_EST_REQ,
287 header.msg_type = L1CTL_DM_FREQ_REQ,
288 header.msg_type = L1CTL_DM_REL_REQ,
289 header.msg_type = L1CTL_TRAFFIC_REQ)"
Harald Welteb3c226e2017-07-30 17:18:01 +0200290 variant (ul_info_tbf) "PRESENCE(header.msg_type = L1CTL_DATA_TBF_REQ)"
Harald Weltef6543322017-07-16 07:35:10 +0200291 variant (payload) "CROSSTAG(fbsb_req, header.msg_type = L1CTL_FBSB_REQ;
292 ccch_mode_req, header.msg_type = L1CTL_CCCH_MODE_REQ;
293 tch_mode_req, header.msg_type = L1CTL_TCH_MODE_REQ;
294 rach_req, header.msg_type = L1CTL_RACH_REQ;
295 par_req, header.msg_type = L1CTL_PARAM_REQ;
296 dm_est_req, header.msg_type = L1CTL_DM_EST_REQ;
297 reset_req, header.msg_type = L1CTL_RESET_REQ;
298 traffic_req, header.msg_type = L1CTL_TRAFFIC_REQ;
Harald Welte00d4dac2017-07-30 00:50:32 +0200299 tbf_cfg_req, header.msg_type = L1CTL_TBF_CFG_REQ;
Harald Weltef6543322017-07-16 07:35:10 +0200300 other, OTHERWISE;
301 )" };
302
303 external function enc_L1ctlUlMessage(in L1ctlUlMessage msg) return octetstring
304 with { extension "prototype(convert) encode(RAW)" };
305 external function dec_L1ctlUlMessage(in octetstring stream) return L1ctlUlMessage
306 with { extension "prototype(convert) decode(RAW)" };
307
Harald Welte52c713c2017-07-16 15:44:44 +0200308 type record L1ctlUlMessageLV {
309 uint16_t len,
310 L1ctlUlMessage msg
311 } with { variant (len) "LENGTHTO(msg)" };
312
313 external function enc_L1ctlUlMessageLV(in L1ctlUlMessageLV msg) return octetstring
314 with { extension "prototype(convert) encode(RAW)" };
315 external function dec_L1ctlUlMessageLV(in octetstring stream) return L1ctlUlMessageLV
316 with { extension "prototype(convert) decode(RAW)" };
317
318 type record L1ctlDlMessageLV {
319 uint16_t len,
320 L1ctlDlMessage msg
321 } with { variant (len) "LENGTHTO(msg)" };
322
323 external function enc_L1ctlDlMessageLV(in L1ctlDlMessageLV msg) return octetstring
324 with { extension "prototype(convert) encode(RAW)" };
325 external function dec_L1ctlDlMessageLV(in octetstring stream) return L1ctlDlMessageLV
326 with { extension "prototype(convert) decode(RAW)" };
327
328
Harald Welte9e4725d2017-07-16 23:18:09 +0200329
330
331 /* for generating RESET_REQ */
332 template L1ctlUlMessage t_L1ctlResetReq(template L1ctlResetType rst_type) := {
333 header := t_L1ctlHeader(L1CTL_RESET_REQ),
334 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200335 ul_info_tbf := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200336 payload := {
337 reset_req := {
338 reset_type := rst_type,
339 padding := '000000'O
340 }
341 }
342 };
343
344 /* for generating FBSB_REQ */
345 template L1ctlUlMessage t_L1CTL_FBSB_REQ(template Arfcn arfcn, template L1ctlFbsbFlags flags, uint8_t sync_info_idx, L1ctlCcchMode ccch_mode, GsmRxLev rxlev_exp) := {
346 header := t_L1ctlHeader(L1CTL_FBSB_REQ),
347 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200348 ul_info_tbf := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200349 payload := {
350 fbsb_req := {
351 arfcn := arfcn,
352 timeout_tdma_frames := 10,
353 freq_err_thresh1 := 10000,
354 freq_err_thresh2 := 800,
355 num_freqerr_avg := 3,
356 flags := flags,
357 sync_info_idx := sync_info_idx,
358 ccch_mode := ccch_mode,
359 rxlev_exp := rxlev_exp
360 }
361 }
362 };
363
364 /* for matching against incoming FBSB_CONF */
365 template L1ctlDlMessage t_L1CTL_FBSB_CONF(template uint8_t result) := {
366 header := t_L1ctlHeader(L1CTL_FBSB_CONF),
367 dl_info := ?,
368 payload := {
369 fbsb_conf := {
370 initial_freq_err := ?,
371 result := result,
372 bsic := ?
373 }
374 }
375 };
376
377 template L1ctlUlMessage t_L1CTL_RACH_REQ(uint8_t ra, uint8_t combined, uint16_t offset) := {
378 header := t_L1ctlHeader(L1CTL_RACH_REQ),
379 ul_info := {
380 chan_nr := t_RslChanNr_RACH(0),
381 link_id := ts_RslLinkID_DCCH(0),
382 padding := '0000'O
383 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200384 ul_info_tbf := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200385 payload := {
386 rach_req := {
387 ra := ra,
388 combined := combined,
389 offset := offset
390 }
391 }
392 }
393
394 template L1ctlUlMessage t_L1CTL_DM_EST_REQ(Arfcn arfcn, RslChannelNr chan_nr, GsmTsc tsc) := {
395 header := t_L1ctlHeader(L1CTL_DM_EST_REQ),
396 ul_info := {
397 chan_nr := chan_nr,
398 link_id := ts_RslLinkID_DCCH(0),
399 padding := '0000'O
400 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200401 ul_info_tbf := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200402 payload := {
403 dm_est_req := {
404 tsc := tsc,
405 h := 0,
406 arfcn := arfcn,
407 hopping := omit,
408 tch_mode := 0,
409 audio_mode := t_L1CTL_AudioModeNone
410 }
411 }
412 }
413
414 template L1ctlUlMessage t_L1CTL_DM_REL_REQ(RslChannelNr chan_nr) := {
Harald Welte143edbd2017-07-17 20:55:42 +0200415 header := t_L1ctlHeader(L1CTL_DM_REL_REQ),
Harald Welte9e4725d2017-07-16 23:18:09 +0200416 ul_info := {
417 chan_nr := chan_nr,
418 link_id := ts_RslLinkID_DCCH(0),
419 padding := '0000'O
420 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200421 ul_info_tbf := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200422 payload := {
423 other := ''O
424 }
425 }
426
427 template L1ctlUlMessage t_L1CTL_DATA_REQ(template RslChannelNr chan_nr, template RslLinkId link_id, octetstring l2_data) := {
428 header := t_L1ctlHeader(L1CTL_DATA_REQ),
429 ul_info := {
430 chan_nr := chan_nr,
431 link_id := link_id,
432 padding := '0000'O
433 },
Harald Welteb3c226e2017-07-30 17:18:01 +0200434 ul_info_tbf := omit,
Harald Welte9e4725d2017-07-16 23:18:09 +0200435 payload := {
436 other := l2_data
437 }
438 }
439
Harald Welte00d4dac2017-07-30 00:50:32 +0200440 template L1ctlUlMessage t_L1CTL_TBF_CFG_REQ(boolean is_uplink, TfiUsfArr tfi_usf) := {
441 header := t_L1ctlHeader(L1CTL_TBF_CFG_REQ),
442 ul_info := omit,
Harald Welteb3c226e2017-07-30 17:18:01 +0200443 ul_info_tbf := omit,
Harald Welte00d4dac2017-07-30 00:50:32 +0200444 payload := {
445 tbf_cfg_req := {
446 tbf_nr := 0,
447 is_uplink := is_uplink,
448 padding := '0000'O,
449 tfi_usf := tfi_usf
450 }
451 }
452 };
453
454 template L1ctlDlMessage t_L1CTL_TBF_CFG_CONF(template boolean is_uplink) := {
455 header := t_L1ctlHeader(L1CTL_TBF_CFG_CONF),
456 dl_info := omit,
457 payload := {
458 tbf_cfg_conf := {
459 tbf_nr := 0,
460 is_uplink := is_uplink,
461 padding := ?,
462 tfi_usf := ?
463 }
464 }
465 };
466
Harald Welteb3c226e2017-07-30 17:18:01 +0200467 template L1ctlUlMessage t_L1CTL_DATA_TBF_REQ(octetstring l2_data, uint8_t tbf_nr := 0) := {
468 header := t_L1ctlHeader(L1CTL_DATA_TBF_REQ),
469 ul_info := omit,
470 ul_info_tbf := {
471 tbf_nr := tbf_nr,
472 padding := '000000'O
473 },
474 payload := {
475 other := l2_data
476 }
477 }
478
Harald Welte9e4725d2017-07-16 23:18:09 +0200479 /* for matching against incoming RACH_CONF */
480 template L1ctlDlMessage t_L1CTL_RACH_CONF := {
481 header := t_L1ctlHeader(L1CTL_RACH_CONF),
482 dl_info := ?,
483 payload := ?
484 };
485
486 /* for matching against incoming RACH_CONF */
487 template L1ctlDlMessage t_L1CTL_DATA_IND(template RslChannelNr chan_nr) := {
488 header := t_L1ctlHeader(L1CTL_DATA_IND),
489 dl_info := {
490 chan_nr := chan_nr,
491 link_id := ?,
492 arfcn := ?,
493 frame_nr := ?,
494 rx_level := ?,
495 snr := ?,
496 num_biterr := ?,
497 fire_crc := ?
498 },
499 payload := {
500 data_ind := ?
501 }
502 };
503
504 template GsmRrMessage t_RR_IMM_ASS(uint8_t ra, uint8_t fn) := {
505 header := t_RrHeader(IMMEDIATE_ASSIGNMENT, ?),
506 payload := {
507 imm_ass := {
508 ded_or_tbf := ?,
509 page_mode := ?,
Harald Welted335cbc2017-07-30 00:51:23 +0200510 chan_desc := *,
511 pkt_chan_desc := *,
Harald Welte9e4725d2017-07-16 23:18:09 +0200512 req_ref := f_compute_ReqRef(ra, fn),
513 timing_advance := ?,
514 mobile_allocation := ?
515 }
516 }
517 };
518
Harald Weltef6543322017-07-16 07:35:10 +0200519} with { encode "RAW" };