blob: 32e1ba6ece1a2fb6e6ec5a9d3208e72cf29595b2 [file] [log] [blame]
Harald Weltef6543322017-07-16 07:35:10 +02001/* LAPDm definitiona according to 3GPP TS 44.006 */
Harald Welted879bd92018-03-12 15:01:23 +01002/* (C) 2017-2018 bh Harald Welte <laforge@gnumonks.org> */
Harald Weltef6543322017-07-16 07:35:10 +02003module LAPDm_Types {
4
5 import from General_Types all;
6 import from Osmocom_Types all;
7
8 type uint3_t LapdmSapi;
9 type BIT2 LapdmSBits;
10 type BIT3 LapdmUBits;
11 type BIT2 LapdmU2Bits;
12
Harald Welte0472ab42018-03-12 15:02:26 +010013 /* 44.006 6.3.2 */
14 const boolean cr_MO_CMD := false;
15 const boolean cr_MO_RSP := true;
16 const boolean cr_MT_CMD := true;
17 const boolean cr_MT_RSP := false;
18
Harald Weltef6543322017-07-16 07:35:10 +020019 /* TS 44.006 Figure 4 */
20 type record LapdmAddressField {
21 BIT1 spare,
Harald Weltec2a5c072017-07-17 20:58:32 +020022 uint2_t lpd,
Harald Weltef6543322017-07-16 07:35:10 +020023 LapdmSapi sapi,
24 boolean c_r,
25 boolean ea
Harald Weltec2a5c072017-07-17 20:58:32 +020026 } with { variant "FIELDORDER(msb)" };
Harald Weltef6543322017-07-16 07:35:10 +020027
Harald Welte9e4725d2017-07-16 23:18:09 +020028 template LapdmAddressField tr_LapdmAddr(template LapdmSapi sapi, template boolean c_r) := {
Harald Weltef6543322017-07-16 07:35:10 +020029 spare := '0'B,
30 lpd := 0,
31 sapi := sapi,
32 c_r := c_r,
33 ea := true
34 };
35
Harald Welted879bd92018-03-12 15:01:23 +010036 template (value) LapdmAddressField ts_LapdmAddr(LapdmSapi sapi, boolean c_r) := {
37 spare := '0'B,
38 lpd := 0,
39 sapi := sapi,
40 c_r := c_r,
41 ea := true
42 };
43
Harald Weltef6543322017-07-16 07:35:10 +020044 type record LapdmCtrlI {
Harald Welte1bbe0b72018-05-10 18:28:15 +020045 uint3_t n_r,
Harald Weltec2a5c072017-07-17 20:58:32 +020046 boolean p,
Harald Welte1bbe0b72018-05-10 18:28:15 +020047 uint3_t n_s,
48 BIT1 spare ('0'B)
49 } with { variant "FIELDORDER(msb)" };
Harald Weltef6543322017-07-16 07:35:10 +020050
51 type record LapdmCtrlS {
Harald Welte1bbe0b72018-05-10 18:28:15 +020052 uint3_t n_r,
Harald Weltec2a5c072017-07-17 20:58:32 +020053 boolean p_f,
Harald Welte1bbe0b72018-05-10 18:28:15 +020054 LapdmSBits s,
55 BIT2 spare ('01'B)
56 } with { variant "FIELDORDER(msb)" };
Harald Weltef6543322017-07-16 07:35:10 +020057
58 type record LapdmCtrlU {
Harald Welte1bbe0b72018-05-10 18:28:15 +020059 LapdmUBits u,
Harald Weltec2a5c072017-07-17 20:58:32 +020060 boolean p_f,
Harald Welte1bbe0b72018-05-10 18:28:15 +020061 LapdmU2Bits u2,
62 BIT2 spare ('11'B)
63 } with { variant "FIELDORDER(msb)" };
Harald Weltef6543322017-07-16 07:35:10 +020064
65 /* TS 44.006 Table 3 */
66 type union LapdmCtrl {
Harald Weltef6543322017-07-16 07:35:10 +020067 LapdmCtrlS s,
Harald Weltec2a5c072017-07-17 20:58:32 +020068 LapdmCtrlU u,
69 LapdmCtrlI i,
70 uint8_t other
71 } with { variant "TAG(u, spare = '11'B;
Harald Weltef6543322017-07-16 07:35:10 +020072 s, spare = '01'B;
Harald Weltec2a5c072017-07-17 20:58:32 +020073 i, spare = '0'B;
74 other, OTHERWISE)" };
75 /* )" }; */
76
77 /* TS 44.006 Table 4 */
Harald Weltef6543322017-07-16 07:35:10 +020078
Harald Welted879bd92018-03-12 15:01:23 +010079 template LapdmCtrl tr_LapdmCtrlS := {
Harald Welte1bbe0b72018-05-10 18:28:15 +020080 s := { n_r := ?, p_f := ?, s := ?, spare := '01'B }
Harald Weltef6543322017-07-16 07:35:10 +020081 };
82
Harald Welted879bd92018-03-12 15:01:23 +010083 template LapdmCtrl tr_LapdmCtrlU := {
Harald Welte1bbe0b72018-05-10 18:28:15 +020084 u := { u := ?, p_f := ?, u2 := ?, spare := '11'B }
Harald Weltef6543322017-07-16 07:35:10 +020085 };
86
87 /* TS 44.006 Table 4 */
Harald Welted879bd92018-03-12 15:01:23 +010088 template LapdmCtrl tr_LapdmCtrlI(template uint3_t nr, template uint3_t ns, template boolean p) := {
Harald Welte1bbe0b72018-05-10 18:28:15 +020089 i := { n_r := nr, p := p, n_s := ns, spare := '0'B }
90 };
91 template (value) LapdmCtrl ts_LapdmCtrlI(uint3_t nr, uint3_t ns, boolean p) := {
92 i := { n_r := nr, p := p, n_s := ns, spare := '0'B }
Harald Weltef6543322017-07-16 07:35:10 +020093 };
94
Harald Welte1bbe0b72018-05-10 18:28:15 +020095
Harald Welted879bd92018-03-12 15:01:23 +010096 template LapdmCtrl tr_LapdmCtrlRR(template uint3_t nr, template boolean pf) modifies tr_LapdmCtrlS := {
Harald Welte1bbe0b72018-05-10 18:28:15 +020097 s := { n_r := nr, p_f := pf, s := '00'B }
98 };
99 template (value) LapdmCtrl ts_LapdmCtrlRR(uint3_t nr, boolean pf) := {
100 s := { n_r := nr, p_f := pf, s := '00'B }
Harald Weltef6543322017-07-16 07:35:10 +0200101 };
102
Harald Welted879bd92018-03-12 15:01:23 +0100103 template LapdmCtrl tr_LapdmCtrlRNR(template uint3_t nr, template boolean pf) modifies tr_LapdmCtrlS := {
Harald Welte1bbe0b72018-05-10 18:28:15 +0200104 s := { n_r := nr, p_f := pf, s := '01'B }
Harald Weltef6543322017-07-16 07:35:10 +0200105 };
106
Harald Welted879bd92018-03-12 15:01:23 +0100107 template LapdmCtrl tr_LapdmCtrlREJ(template uint3_t nr, template boolean pf) modifies tr_LapdmCtrlS := {
Harald Welte1bbe0b72018-05-10 18:28:15 +0200108 s := { n_r := nr, p_f := pf, s := '10'B }
Harald Weltef6543322017-07-16 07:35:10 +0200109 };
110
Harald Welte1bbe0b72018-05-10 18:28:15 +0200111 template LapdmCtrl tr_LapdmCtrlSABM(template boolean p) := {
112 u := { u := '001'B, p_f := p, u2 := '11'B, spare := '11'B }
Harald Weltef6543322017-07-16 07:35:10 +0200113 };
Harald Welted879bd92018-03-12 15:01:23 +0100114 template (value) LapdmCtrl ts_LapdmCtrlSABM(boolean p) := {
Harald Welte1bbe0b72018-05-10 18:28:15 +0200115 u := { u := '001'B, p_f := p, u2 := '11'B, spare := '11'B }
Harald Welted879bd92018-03-12 15:01:23 +0100116 };
Harald Weltef6543322017-07-16 07:35:10 +0200117
Harald Welte1bbe0b72018-05-10 18:28:15 +0200118 template LapdmCtrl tr_LapdmCtrlDM(template boolean f) := {
119 u := { u := '000'B, p_f := f, u2 := '11'B, spare := '11'B }
Harald Weltef6543322017-07-16 07:35:10 +0200120 };
121
Harald Welte1bbe0b72018-05-10 18:28:15 +0200122 template LapdmCtrl tr_LapdmCtrlUI(template boolean p := false) := {
123 u := { u := '000'B, p_f := p, u2 := '00'B, spare := '11'B }
Harald Weltef6543322017-07-16 07:35:10 +0200124 };
Harald Welte1bbe0b72018-05-10 18:28:15 +0200125 template (value) LapdmCtrl ts_LapdmCtrlUI(boolean p := false) := {
126 u := { u := '000'B, p_f := p, u2 := '00'B, spare := '11'B }
Harald Welted879bd92018-03-12 15:01:23 +0100127 };
Harald Weltef6543322017-07-16 07:35:10 +0200128
Harald Welte1bbe0b72018-05-10 18:28:15 +0200129 template LapdmCtrl tr_LapdmCtrlDISC(template boolean p) := {
130 u := { u := '010'B, p_f := p, u2 := '00'B, spare := '11'B }
Harald Weltef6543322017-07-16 07:35:10 +0200131 };
Harald Welted879bd92018-03-12 15:01:23 +0100132 template LapdmCtrl ts_LapdmCtrlDISC(boolean p) := {
Harald Welte1bbe0b72018-05-10 18:28:15 +0200133 u := { u := '010'B, p_f := p, u2 := '00'B, spare := '11'B }
Harald Welted879bd92018-03-12 15:01:23 +0100134 };
Harald Weltef6543322017-07-16 07:35:10 +0200135
Harald Welted879bd92018-03-12 15:01:23 +0100136 template LapdmCtrl tr_LapdmCtrlUA(template boolean f) modifies tr_LapdmCtrlU := {
Harald Welte1bbe0b72018-05-10 18:28:15 +0200137 u := { u := '011'B, p_f := f, u2 := '00'B, spare := '11'B }
Harald Weltef6543322017-07-16 07:35:10 +0200138 };
Harald Welted879bd92018-03-12 15:01:23 +0100139 template (value) LapdmCtrl ts_LapdmCtrlUA(boolean f) := {
Harald Welte1bbe0b72018-05-10 18:28:15 +0200140 u := { u := '011'B, p_f := f, u2 := '00'B, spare := '11'B }
Harald Welted879bd92018-03-12 15:01:23 +0100141 };
142
143
Harald Weltef6543322017-07-16 07:35:10 +0200144
Harald Welte1bd7c322017-07-17 20:59:46 +0200145 external function dec_LapdmAddressField(in octetstring stream) return LapdmAddressField
146 with { extension "prototype(convert) decode(RAW)" };
147
148 external function dec_LapdmCtrl(in octetstring stream) return LapdmCtrl
149 with { extension "prototype(convert) decode(RAW)" };
150
151 external function dec_LapdmCtrlU(in octetstring stream) return LapdmCtrlU
152 with { extension "prototype(convert) decode(RAW)" };
153
Harald Weltef6543322017-07-16 07:35:10 +0200154 /* Formats B, Bter and B4 are used on DCCHs for frames containing an information field:
155 /* - format Bter is used on request of higher layers if and only if short L2 header type 1 is
156 * supported and a UI command is to be transmitted on SAPI 0 */
157 /* - format B4 is used for UI frames transmitted by the network on SACCH; */
158 /* - format B is applied in all other cases. */
159 /* Format Bbis is used only on BCCH, PCH, NCH, and AGCH.
160
161 /* Format B */
Harald Welted879bd92018-03-12 15:01:23 +0100162 type record LapdmFrameAB {
Harald Weltef6543322017-07-16 07:35:10 +0200163 LapdmAddressField addr,
164 LapdmCtrl ctrl,
Harald Welted879bd92018-03-12 15:01:23 +0100165 uint6_t len,
Harald Welted4ba7ff2017-07-17 21:00:48 +0200166 boolean m,
Harald Welted879bd92018-03-12 15:01:23 +0100167 uint1_t el,
168 octetstring payload /* zero-length in Frame A */
Harald Welted4ba7ff2017-07-17 21:00:48 +0200169 } with { variant (len) "LENGTHTO(payload)"
170 variant "FIELDORDER(msb)" };
Harald Weltef6543322017-07-16 07:35:10 +0200171
Harald Welted879bd92018-03-12 15:01:23 +0100172 external function enc_LapdmFrameAB(in LapdmFrameAB si) return octetstring
Harald Weltef6543322017-07-16 07:35:10 +0200173 with { extension "prototype(convert) encode(RAW)" };
Harald Welted879bd92018-03-12 15:01:23 +0100174 external function dec_LapdmFrameAB(in octetstring stream) return LapdmFrameAB
Harald Weltef6543322017-07-16 07:35:10 +0200175 with { extension "prototype(convert) decode(RAW)" };
176
Harald Weltef6543322017-07-16 07:35:10 +0200177 /* Format B4 */
178 type record LapdmFrameB4 {
179 LapdmAddressField addr,
180 LapdmCtrl ctrl,
181 octetstring payload
182 } with { variant "" };
183
184 external function enc_LapdmFrameB4(in LapdmFrameB4 si) return octetstring
185 with { extension "prototype(convert) encode(RAW)" };
186 external function dec_LapdmFrameB4(in octetstring stream) return LapdmFrameB4
187 with { extension "prototype(convert) decode(RAW)" };
188
Harald Weltec2a5c072017-07-17 20:58:32 +0200189 type record LapdmFrameBbis {
190 octetstring payload
191 } with { variant "" };
192
193 external function enc_LapdmFrameBbis(in LapdmFrameBbis si) return octetstring
194 with { extension "prototype(convert) encode(RAW)" };
195 external function dec_LapdmFrameBbis(in octetstring stream) return LapdmFrameBbis
196 with { extension "prototype(convert) decode(RAW)" };
197
198 type union LapdmFrame {
Harald Welted879bd92018-03-12 15:01:23 +0100199 LapdmFrameAB ab,
Harald Weltec2a5c072017-07-17 20:58:32 +0200200 LapdmFrameBbis bbis,
201 LapdmFrameB4 b4
202 } with { variant "" };
203
204 external function enc_LapdmFrame(in LapdmFrame si) return octetstring
205 with { extension "prototype(convert) encode(RAW)" };
206 /* automatic decoding to the generic LapdmFrame will not work, you have to call one of the
207 * type-specific decoder routines above */
208
Harald Welte0472ab42018-03-12 15:02:26 +0100209 /* SABM frame with L3 payload */
210 template (value) LapdmFrame ts_LAPDm_SABM(LapdmSapi sapi, boolean c_r, boolean p,
211 octetstring l3) := {
212 ab := {
213 addr := ts_LapdmAddr(sapi, c_r),
214 ctrl := ts_LapdmCtrlSABM(p),
215 len := 0, /* overwritten in encoder */
216 m := false,
217 el := 1,
218 payload := l3
219 }
220 }
221 template LapdmFrame tr_LAPDm_SABM(template LapdmSapi sapi, template boolean c_r,
222 template boolean p, template octetstring l3) := {
223 ab := {
224 addr := tr_LapdmAddr(sapi, c_r),
225 ctrl := tr_LapdmCtrlSABM(p),
226 len := ?,
227 m := false,
228 el := 1,
229 payload := l3
230 }
231 }
232
233 template (value) LapdmFrame ts_LAPDm_UA(LapdmSapi sapi, boolean c_r, boolean f,
234 octetstring l3) := {
235 ab := {
236 addr := ts_LapdmAddr(sapi, c_r),
237 ctrl := ts_LapdmCtrlUA(f),
238 len := 0, /* overwritten in encoder */
239 m := false,
240 el := 1,
241 payload := l3
242 }
243 }
244 template LapdmFrame tr_LAPDm_UA(template LapdmSapi sapi, template boolean c_r,
245 template boolean f, template octetstring l3) := {
246 ab := {
247 addr := tr_LapdmAddr(sapi, c_r),
248 ctrl := tr_LapdmCtrlUA(f),
249 len := ?,
250 m := false,
251 el := 1,
252 payload := l3
253 }
254 }
255
256 template LapdmFrame ts_LAPDm_DISC(LapdmSapi sapi, boolean c_r, boolean p) := {
257 ab := {
258 addr := ts_LapdmAddr(sapi, c_r),
259 ctrl := ts_LapdmCtrlDISC(p),
260 len := 0,
261 m := false,
262 el := 1,
263 payload := ''O
264 }
265 }
266 template LapdmFrame tr_LAPDm_DISC(template LapdmSapi sapi, template boolean c_r,
267 template boolean p) := {
268 ab := {
269 addr := tr_LapdmAddr(sapi, c_r),
270 ctrl := tr_LapdmCtrlDISC(p),
271 len := ?,
272 m := false,
273 el := 1,
274 payload := ''O
275 }
276 }
277
Harald Weltee613f962018-04-18 22:38:16 +0200278 template LapdmFrame ts_LAPDm_UI(LapdmSapi sapi, boolean c_r, octetstring l3) := {
Harald Welte0472ab42018-03-12 15:02:26 +0100279 ab := {
280 addr := ts_LapdmAddr(sapi, c_r),
Harald Weltee613f962018-04-18 22:38:16 +0200281 ctrl := ts_LapdmCtrlUI,
Harald Welte0472ab42018-03-12 15:02:26 +0100282 len := 0,
283 m := false,
284 el := 1,
285 payload := l3
286 }
287 }
288 template LapdmFrame tr_LAPDm_UI(template LapdmSapi sapi, template boolean c_r,
Harald Weltee613f962018-04-18 22:38:16 +0200289 template octetstring l3) := {
Harald Welte0472ab42018-03-12 15:02:26 +0100290 ab := {
291 addr := tr_LapdmAddr(sapi, c_r),
Harald Weltee613f962018-04-18 22:38:16 +0200292 ctrl := tr_LapdmCtrlUI,
Harald Welte0472ab42018-03-12 15:02:26 +0100293 len := ?,
294 m := false,
295 el := 1,
296 payload := l3
297 }
298 }
299
Harald Weltee613f962018-04-18 22:38:16 +0200300 template LapdmFrame ts_LAPDm_B4_UI(LapdmSapi sapi, boolean c_r, octetstring l3) := {
Harald Welte0472ab42018-03-12 15:02:26 +0100301 b4 := {
302 addr := ts_LapdmAddr(sapi, c_r),
Harald Weltee613f962018-04-18 22:38:16 +0200303 ctrl := ts_LapdmCtrlUI,
Harald Welte0472ab42018-03-12 15:02:26 +0100304 payload := l3
305 }
306 }
307 template LapdmFrame tr_LAPDm_B4_UI(template LapdmSapi sapi, template boolean c_r,
Harald Weltee613f962018-04-18 22:38:16 +0200308 template octetstring l3) := {
Harald Welte0472ab42018-03-12 15:02:26 +0100309 b4 := {
310 addr := tr_LapdmAddr(sapi, c_r),
Harald Weltee613f962018-04-18 22:38:16 +0200311 ctrl := tr_LapdmCtrlUI,
Harald Welte0472ab42018-03-12 15:02:26 +0100312 payload := l3
313 }
314 }
315
Harald Weltee613f962018-04-18 22:38:16 +0200316 template LapdmFrame tr_LAPDm_I(template LapdmSapi sapi, template boolean c_r,
317 template boolean p, template uint3_t nr,
318 template uint3_t ns, template octetstring l3) := {
319 ab := {
320 addr := tr_LapdmAddr(sapi, c_r),
321 ctrl := tr_LapdmCtrlI(nr, ns, p),
322 len := ?,
323 m := false,
324 el := 1,
325 payload := l3
326 }
327 }
328 template (value) LapdmFrame ts_LAPDm_I(LapdmSapi sapi, boolean c_r, boolean p, uint3_t nr,
329 uint3_t ns, octetstring l3) := {
330 ab := {
331 addr := ts_LapdmAddr(sapi, c_r),
332 ctrl := ts_LapdmCtrlI(nr, ns, p),
333 len := 0,
334 m := false,
335 el := 1,
336 payload := l3
337 }
338 }
339
340 template LapdmFrame tr_LAPDm_RR(template LapdmSapi sapi, template boolean c_r,
341 template boolean p, template uint3_t nr) := {
342 ab := {
343 addr := tr_LapdmAddr(sapi, c_r),
344 ctrl := tr_LapdmCtrlRR(nr, p),
345 len := 0,
346 m := false,
347 el := 1,
348 payload := ''O
349 }
350 }
351 template (value) LapdmFrame ts_LAPDm_RR(LapdmSapi sapi, boolean c_r,
352 boolean p, uint3_t nr) := {
353 ab := {
354 addr := ts_LapdmAddr(sapi, c_r),
355 ctrl := ts_LapdmCtrlRR(nr, p),
356 len := 0,
357 m := false,
358 el := 1,
359 payload := ''O
360 }
361 }
362
Harald Welte0472ab42018-03-12 15:02:26 +0100363
364
Harald Weltec2a5c072017-07-17 20:58:32 +0200365} with { encode "RAW"; /*variant "FIELDORDER(msb)" */}