blob: 487748d7686ac7eeb915c00067c8a61ad5da2b23 [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 Welteffcad682017-07-30 22:51:04 +020045 BIT1 spare ('0'B),
Harald Weltef6543322017-07-16 07:35:10 +020046 uint3_t n_s,
Harald Weltec2a5c072017-07-17 20:58:32 +020047 boolean p,
48 uint3_t n_r
49 } with { variant "FIELDORDER(lsb)" };
Harald Weltef6543322017-07-16 07:35:10 +020050
51 type record LapdmCtrlS {
Harald Welteffcad682017-07-30 22:51:04 +020052 BIT2 spare ('01'B),
Harald Weltef6543322017-07-16 07:35:10 +020053 LapdmSBits s,
Harald Weltec2a5c072017-07-17 20:58:32 +020054 boolean p_f,
55 uint3_t n_r
56 } with { variant "FIELDORDER(lsb)" };
Harald Weltef6543322017-07-16 07:35:10 +020057
58 type record LapdmCtrlU {
Harald Welteffcad682017-07-30 22:51:04 +020059 BIT2 spare ('11'B),
Harald Weltef6543322017-07-16 07:35:10 +020060 LapdmU2Bits u2,
Harald Weltec2a5c072017-07-17 20:58:32 +020061 boolean p_f,
62 LapdmUBits u
63 } with { variant "FIELDORDER(lsb)" };
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 Weltec2a5c072017-07-17 20:58:32 +020080 s := { spare := '01'B, s := ?, p_f := ?, n_r := ? }
Harald Weltef6543322017-07-16 07:35:10 +020081 };
82
Harald Welted879bd92018-03-12 15:01:23 +010083 template LapdmCtrl tr_LapdmCtrlU := {
Harald Weltec2a5c072017-07-17 20:58:32 +020084 u := { spare := '11'B, u2 := ?, p_f := ?, u := ? }
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 Weltec2a5c072017-07-17 20:58:32 +020089 i := { spare := '0'B, n_s := ns, p := p, n_r := nr }
Harald Weltef6543322017-07-16 07:35:10 +020090 };
91
Harald Welted879bd92018-03-12 15:01:23 +010092 template LapdmCtrl tr_LapdmCtrlRR(template uint3_t nr, template boolean pf) modifies tr_LapdmCtrlS := {
Harald Weltec2a5c072017-07-17 20:58:32 +020093 s := { s:= '00'B, p_f := pf, n_r := nr }
Harald Weltef6543322017-07-16 07:35:10 +020094 };
95
Harald Welted879bd92018-03-12 15:01:23 +010096 template LapdmCtrl tr_LapdmCtrlRNR(template uint3_t nr, template boolean pf) modifies tr_LapdmCtrlS := {
Harald Weltec2a5c072017-07-17 20:58:32 +020097 s := { s:= '01'B, p_f := pf, n_r := nr }
Harald Weltef6543322017-07-16 07:35:10 +020098 };
99
Harald Welted879bd92018-03-12 15:01:23 +0100100 template LapdmCtrl tr_LapdmCtrlREJ(template uint3_t nr, template boolean pf) modifies tr_LapdmCtrlS := {
Harald Weltec2a5c072017-07-17 20:58:32 +0200101 s := { s:= '10'B, p_f := pf, n_r := nr }
Harald Weltef6543322017-07-16 07:35:10 +0200102 };
103
Harald Welted879bd92018-03-12 15:01:23 +0100104 template LapdmCtrl tr_LapdmCtrlSABM(template boolean p) modifies tr_LapdmCtrlU := {
Harald Weltec2a5c072017-07-17 20:58:32 +0200105 u := { u2 := '11'B, p_f := p, u := '001'B }
Harald Weltef6543322017-07-16 07:35:10 +0200106 };
Harald Welted879bd92018-03-12 15:01:23 +0100107 template (value) LapdmCtrl ts_LapdmCtrlSABM(boolean p) := {
108 u := { spare := '11'B, u2 := '11'B, p_f := p, u := '001'B }
109 };
Harald Weltef6543322017-07-16 07:35:10 +0200110
Harald Welted879bd92018-03-12 15:01:23 +0100111 template LapdmCtrl tr_LapdmCtrlDM(template boolean f) modifies tr_LapdmCtrlU := {
Harald Weltec2a5c072017-07-17 20:58:32 +0200112 u := { u2 := '11'B, p_f := f, u := '000'B }
Harald Weltef6543322017-07-16 07:35:10 +0200113 };
114
Harald Welted879bd92018-03-12 15:01:23 +0100115 template LapdmCtrl tr_LapdmCtrlUI(template boolean p) modifies tr_LapdmCtrlU := {
Harald Weltec2a5c072017-07-17 20:58:32 +0200116 u := { u2 := '00'B, p_f := p, u := '000'B }
Harald Weltef6543322017-07-16 07:35:10 +0200117 };
Harald Welted879bd92018-03-12 15:01:23 +0100118 template (value) LapdmCtrl ts_LapdmCtrlUI(boolean p) := {
119 u := { spare := '11'B, u2 := '00'B, p_f := p, u := '000'B }
120 };
Harald Weltef6543322017-07-16 07:35:10 +0200121
Harald Welted879bd92018-03-12 15:01:23 +0100122 template LapdmCtrl tr_LapdmCtrlDISC(template boolean p) modifies tr_LapdmCtrlU := {
Harald Weltec2a5c072017-07-17 20:58:32 +0200123 u := { u2 := '00'B, p_f := p, u := '010'B }
Harald Weltef6543322017-07-16 07:35:10 +0200124 };
Harald Welted879bd92018-03-12 15:01:23 +0100125 template LapdmCtrl ts_LapdmCtrlDISC(boolean p) := {
126 u := { spare := '11'B, u2 := '00'B, p_f := p, u := '010'B }
127 };
Harald Weltef6543322017-07-16 07:35:10 +0200128
Harald Welted879bd92018-03-12 15:01:23 +0100129 template LapdmCtrl tr_LapdmCtrlUA(template boolean f) modifies tr_LapdmCtrlU := {
Harald Welted4ba7ff2017-07-17 21:00:48 +0200130 u := { u2 := '00'B, p_f := f, u := '011'B }
Harald Weltef6543322017-07-16 07:35:10 +0200131 };
Harald Welted879bd92018-03-12 15:01:23 +0100132 template (value) LapdmCtrl ts_LapdmCtrlUA(boolean f) := {
133 u := { spare := '11'B, u2 := '00'B, p_f := f, u := '011'B }
134 };
135
136
Harald Weltef6543322017-07-16 07:35:10 +0200137
Harald Welte1bd7c322017-07-17 20:59:46 +0200138 external function dec_LapdmAddressField(in octetstring stream) return LapdmAddressField
139 with { extension "prototype(convert) decode(RAW)" };
140
141 external function dec_LapdmCtrl(in octetstring stream) return LapdmCtrl
142 with { extension "prototype(convert) decode(RAW)" };
143
144 external function dec_LapdmCtrlU(in octetstring stream) return LapdmCtrlU
145 with { extension "prototype(convert) decode(RAW)" };
146
Harald Weltef6543322017-07-16 07:35:10 +0200147 /* Formats B, Bter and B4 are used on DCCHs for frames containing an information field:
148 /* - format Bter is used on request of higher layers if and only if short L2 header type 1 is
149 * supported and a UI command is to be transmitted on SAPI 0 */
150 /* - format B4 is used for UI frames transmitted by the network on SACCH; */
151 /* - format B is applied in all other cases. */
152 /* Format Bbis is used only on BCCH, PCH, NCH, and AGCH.
153
154 /* Format B */
Harald Welted879bd92018-03-12 15:01:23 +0100155 type record LapdmFrameAB {
Harald Weltef6543322017-07-16 07:35:10 +0200156 LapdmAddressField addr,
157 LapdmCtrl ctrl,
Harald Welted879bd92018-03-12 15:01:23 +0100158 uint6_t len,
Harald Welted4ba7ff2017-07-17 21:00:48 +0200159 boolean m,
Harald Welted879bd92018-03-12 15:01:23 +0100160 uint1_t el,
161 octetstring payload /* zero-length in Frame A */
Harald Welted4ba7ff2017-07-17 21:00:48 +0200162 } with { variant (len) "LENGTHTO(payload)"
163 variant "FIELDORDER(msb)" };
Harald Weltef6543322017-07-16 07:35:10 +0200164
Harald Welted879bd92018-03-12 15:01:23 +0100165 external function enc_LapdmFrameAB(in LapdmFrameAB si) return octetstring
Harald Weltef6543322017-07-16 07:35:10 +0200166 with { extension "prototype(convert) encode(RAW)" };
Harald Welted879bd92018-03-12 15:01:23 +0100167 external function dec_LapdmFrameAB(in octetstring stream) return LapdmFrameAB
Harald Weltef6543322017-07-16 07:35:10 +0200168 with { extension "prototype(convert) decode(RAW)" };
169
Harald Weltef6543322017-07-16 07:35:10 +0200170 /* Format B4 */
171 type record LapdmFrameB4 {
172 LapdmAddressField addr,
173 LapdmCtrl ctrl,
174 octetstring payload
175 } with { variant "" };
176
177 external function enc_LapdmFrameB4(in LapdmFrameB4 si) return octetstring
178 with { extension "prototype(convert) encode(RAW)" };
179 external function dec_LapdmFrameB4(in octetstring stream) return LapdmFrameB4
180 with { extension "prototype(convert) decode(RAW)" };
181
Harald Weltec2a5c072017-07-17 20:58:32 +0200182 type record LapdmFrameBbis {
183 octetstring payload
184 } with { variant "" };
185
186 external function enc_LapdmFrameBbis(in LapdmFrameBbis si) return octetstring
187 with { extension "prototype(convert) encode(RAW)" };
188 external function dec_LapdmFrameBbis(in octetstring stream) return LapdmFrameBbis
189 with { extension "prototype(convert) decode(RAW)" };
190
191 type union LapdmFrame {
Harald Welted879bd92018-03-12 15:01:23 +0100192 LapdmFrameAB ab,
Harald Weltec2a5c072017-07-17 20:58:32 +0200193 LapdmFrameBbis bbis,
194 LapdmFrameB4 b4
195 } with { variant "" };
196
197 external function enc_LapdmFrame(in LapdmFrame si) return octetstring
198 with { extension "prototype(convert) encode(RAW)" };
199 /* automatic decoding to the generic LapdmFrame will not work, you have to call one of the
200 * type-specific decoder routines above */
201
Harald Welte0472ab42018-03-12 15:02:26 +0100202 /* SABM frame with L3 payload */
203 template (value) LapdmFrame ts_LAPDm_SABM(LapdmSapi sapi, boolean c_r, boolean p,
204 octetstring l3) := {
205 ab := {
206 addr := ts_LapdmAddr(sapi, c_r),
207 ctrl := ts_LapdmCtrlSABM(p),
208 len := 0, /* overwritten in encoder */
209 m := false,
210 el := 1,
211 payload := l3
212 }
213 }
214 template LapdmFrame tr_LAPDm_SABM(template LapdmSapi sapi, template boolean c_r,
215 template boolean p, template octetstring l3) := {
216 ab := {
217 addr := tr_LapdmAddr(sapi, c_r),
218 ctrl := tr_LapdmCtrlSABM(p),
219 len := ?,
220 m := false,
221 el := 1,
222 payload := l3
223 }
224 }
225
226 template (value) LapdmFrame ts_LAPDm_UA(LapdmSapi sapi, boolean c_r, boolean f,
227 octetstring l3) := {
228 ab := {
229 addr := ts_LapdmAddr(sapi, c_r),
230 ctrl := ts_LapdmCtrlUA(f),
231 len := 0, /* overwritten in encoder */
232 m := false,
233 el := 1,
234 payload := l3
235 }
236 }
237 template LapdmFrame tr_LAPDm_UA(template LapdmSapi sapi, template boolean c_r,
238 template boolean f, template octetstring l3) := {
239 ab := {
240 addr := tr_LapdmAddr(sapi, c_r),
241 ctrl := tr_LapdmCtrlUA(f),
242 len := ?,
243 m := false,
244 el := 1,
245 payload := l3
246 }
247 }
248
249 template LapdmFrame ts_LAPDm_DISC(LapdmSapi sapi, boolean c_r, boolean p) := {
250 ab := {
251 addr := ts_LapdmAddr(sapi, c_r),
252 ctrl := ts_LapdmCtrlDISC(p),
253 len := 0,
254 m := false,
255 el := 1,
256 payload := ''O
257 }
258 }
259 template LapdmFrame tr_LAPDm_DISC(template LapdmSapi sapi, template boolean c_r,
260 template boolean p) := {
261 ab := {
262 addr := tr_LapdmAddr(sapi, c_r),
263 ctrl := tr_LapdmCtrlDISC(p),
264 len := ?,
265 m := false,
266 el := 1,
267 payload := ''O
268 }
269 }
270
271 template LapdmFrame ts_LAPDm_UI(LapdmSapi sapi, boolean c_r, boolean p, octetstring l3) := {
272 ab := {
273 addr := ts_LapdmAddr(sapi, c_r),
274 ctrl := ts_LapdmCtrlUI(p),
275 len := 0,
276 m := false,
277 el := 1,
278 payload := l3
279 }
280 }
281 template LapdmFrame tr_LAPDm_UI(template LapdmSapi sapi, template boolean c_r,
282 template boolean p, template octetstring l3) := {
283 ab := {
284 addr := tr_LapdmAddr(sapi, c_r),
285 ctrl := tr_LapdmCtrlUI(p),
286 len := ?,
287 m := false,
288 el := 1,
289 payload := l3
290 }
291 }
292
293 template LapdmFrame ts_LAPDm_B4_UI(LapdmSapi sapi, boolean c_r, boolean p, octetstring l3) := {
294 b4 := {
295 addr := ts_LapdmAddr(sapi, c_r),
296 ctrl := ts_LapdmCtrlUI(p),
297 payload := l3
298 }
299 }
300 template LapdmFrame tr_LAPDm_B4_UI(template LapdmSapi sapi, template boolean c_r,
301 template boolean p, template octetstring l3) := {
302 b4 := {
303 addr := tr_LapdmAddr(sapi, c_r),
304 ctrl := tr_LapdmCtrlUI(p),
305 payload := l3
306 }
307 }
308
309
310
Harald Weltec2a5c072017-07-17 20:58:32 +0200311} with { encode "RAW"; /*variant "FIELDORDER(msb)" */}