| /* LAPDm definitiona according to 3GPP TS 44.006 */ |
| /* (C) 2017 bh Harald Welte <laforge@gnumonks.org> */ |
| module LAPDm_Types { |
| |
| import from General_Types all; |
| import from Osmocom_Types all; |
| |
| type uint3_t LapdmSapi; |
| type BIT2 LapdmSBits; |
| type BIT3 LapdmUBits; |
| type BIT2 LapdmU2Bits; |
| |
| type record LapdmLengthIndicator { |
| uint6_t len, |
| boolean m, |
| uint1_t el |
| } with { variant "FIELDORDER(msb)" }; |
| |
| template LapdmLengthIndicator t_LapdmLengthIndicator(template uint6_t len, boolean m := false) := { |
| len := len, |
| m := m, |
| el := 1 |
| }; |
| |
| /* TS 44.006 Figure 4 */ |
| type record LapdmAddressField { |
| BIT1 spare, |
| uint2_t lpd, |
| LapdmSapi sapi, |
| boolean c_r, |
| boolean ea |
| } with { variant "FIELDORDER(msb)" }; |
| |
| template LapdmAddressField tr_LapdmAddr(template LapdmSapi sapi, template boolean c_r) := { |
| spare := '0'B, |
| lpd := 0, |
| sapi := sapi, |
| c_r := c_r, |
| ea := true |
| }; |
| |
| type record LapdmCtrlI { |
| BIT1 spare ('0'B), |
| uint3_t n_s, |
| boolean p, |
| uint3_t n_r |
| } with { variant "FIELDORDER(lsb)" }; |
| |
| type record LapdmCtrlS { |
| BIT2 spare ('01'B), |
| LapdmSBits s, |
| boolean p_f, |
| uint3_t n_r |
| } with { variant "FIELDORDER(lsb)" }; |
| |
| type record LapdmCtrlU { |
| BIT2 spare ('11'B), |
| LapdmU2Bits u2, |
| boolean p_f, |
| LapdmUBits u |
| } with { variant "FIELDORDER(lsb)" }; |
| |
| /* TS 44.006 Table 3 */ |
| type union LapdmCtrl { |
| LapdmCtrlS s, |
| LapdmCtrlU u, |
| LapdmCtrlI i, |
| uint8_t other |
| } with { variant "TAG(u, spare = '11'B; |
| s, spare = '01'B; |
| i, spare = '0'B; |
| other, OTHERWISE)" }; |
| /* )" }; */ |
| |
| /* TS 44.006 Table 4 */ |
| |
| template LapdmCtrl t_LapdmCtrlS := { |
| s := { spare := '01'B, s := ?, p_f := ?, n_r := ? } |
| }; |
| |
| template LapdmCtrl t_LapdmCtrlU := { |
| u := { spare := '11'B, u2 := ?, p_f := ?, u := ? } |
| }; |
| |
| /* TS 44.006 Table 4 */ |
| template LapdmCtrl t_LapdmCtrlI(template uint3_t nr, template uint3_t ns, template boolean p) := { |
| i := { spare := '0'B, n_s := ns, p := p, n_r := nr } |
| }; |
| |
| template LapdmCtrl t_LapdmCtrlRR(template uint3_t nr, template boolean pf) modifies t_LapdmCtrlS := { |
| s := { s:= '00'B, p_f := pf, n_r := nr } |
| }; |
| |
| template LapdmCtrl t_LapdmCtrlRNR(template uint3_t nr, template boolean pf) modifies t_LapdmCtrlS := { |
| s := { s:= '01'B, p_f := pf, n_r := nr } |
| }; |
| |
| template LapdmCtrl t_LapdmCtrlREJ(template uint3_t nr, template boolean pf) modifies t_LapdmCtrlS := { |
| s := { s:= '10'B, p_f := pf, n_r := nr } |
| }; |
| |
| template LapdmCtrl t_LapdmCtrlSABM(template boolean p) modifies t_LapdmCtrlU := { |
| u := { u2 := '11'B, p_f := p, u := '001'B } |
| }; |
| |
| template LapdmCtrl t_LapdmCtrlDM(template boolean f) modifies t_LapdmCtrlU := { |
| u := { u2 := '11'B, p_f := f, u := '000'B } |
| }; |
| |
| template LapdmCtrl t_LapdmCtrlUI(template boolean p) modifies t_LapdmCtrlU := { |
| u := { u2 := '00'B, p_f := p, u := '000'B } |
| }; |
| |
| template LapdmCtrl t_LapdmCtrlDISC(template boolean p) modifies t_LapdmCtrlU := { |
| u := { u2 := '00'B, p_f := p, u := '010'B } |
| }; |
| |
| template LapdmCtrl t_LapdmCtrlUA(template boolean f) modifies t_LapdmCtrlU := { |
| u := { u2 := '00'B, p_f := f, u := '011'B } |
| }; |
| |
| external function dec_LapdmAddressField(in octetstring stream) return LapdmAddressField |
| with { extension "prototype(convert) decode(RAW)" }; |
| |
| external function dec_LapdmCtrl(in octetstring stream) return LapdmCtrl |
| with { extension "prototype(convert) decode(RAW)" }; |
| |
| external function dec_LapdmCtrlU(in octetstring stream) return LapdmCtrlU |
| with { extension "prototype(convert) decode(RAW)" }; |
| |
| external function dec_LapdmLengthIndicator(in octetstring stream) return LapdmLengthIndicator |
| with { extension "prototype(convert) decode(RAW)" }; |
| |
| /* Format A is used on DCCHs for frames where there is no information field */ |
| type record LapdmFrameA { |
| LapdmAddressField addr, |
| LapdmCtrl ctrl, |
| LapdmLengthIndicator len |
| } with { variant "" }; |
| |
| external function enc_LapdmFrameA(in LapdmFrameA si) return octetstring |
| with { extension "prototype(convert) encode(RAW)" }; |
| external function dec_LapdmFrameA(in octetstring stream) return LapdmFrameA |
| with { extension "prototype(convert) decode(RAW)" }; |
| |
| /* Formats B, Bter and B4 are used on DCCHs for frames containing an information field: |
| /* - format Bter is used on request of higher layers if and only if short L2 header type 1 is |
| * supported and a UI command is to be transmitted on SAPI 0 */ |
| /* - format B4 is used for UI frames transmitted by the network on SACCH; */ |
| /* - format B is applied in all other cases. */ |
| /* Format Bbis is used only on BCCH, PCH, NCH, and AGCH. |
| |
| /* Format B */ |
| type record LapdmFrameB { |
| LapdmAddressField addr, |
| LapdmCtrl ctrl, |
| uint6_t len, |
| boolean m, |
| uint1_t el (1), |
| octetstring payload |
| } with { variant (len) "LENGTHTO(payload)" |
| variant "FIELDORDER(msb)" }; |
| |
| external function enc_LapdmFrameB(in LapdmFrameB si) return octetstring |
| with { extension "prototype(convert) encode(RAW)" }; |
| external function dec_LapdmFrameB(in octetstring stream) return LapdmFrameB |
| with { extension "prototype(convert) decode(RAW)" }; |
| |
| /* Format B4 */ |
| type record LapdmFrameB4 { |
| LapdmAddressField addr, |
| LapdmCtrl ctrl, |
| octetstring payload |
| } with { variant "" }; |
| |
| external function enc_LapdmFrameB4(in LapdmFrameB4 si) return octetstring |
| with { extension "prototype(convert) encode(RAW)" }; |
| external function dec_LapdmFrameB4(in octetstring stream) return LapdmFrameB4 |
| with { extension "prototype(convert) decode(RAW)" }; |
| |
| type record LapdmFrameBbis { |
| octetstring payload |
| } with { variant "" }; |
| |
| external function enc_LapdmFrameBbis(in LapdmFrameBbis si) return octetstring |
| with { extension "prototype(convert) encode(RAW)" }; |
| external function dec_LapdmFrameBbis(in octetstring stream) return LapdmFrameBbis |
| with { extension "prototype(convert) decode(RAW)" }; |
| |
| type union LapdmFrame { |
| LapdmFrameA a, |
| LapdmFrameB b, |
| LapdmFrameBbis bbis, |
| LapdmFrameB4 b4 |
| } with { variant "" }; |
| |
| external function enc_LapdmFrame(in LapdmFrame si) return octetstring |
| with { extension "prototype(convert) encode(RAW)" }; |
| /* automatic decoding to the generic LapdmFrame will not work, you have to call one of the |
| * type-specific decoder routines above */ |
| |
| } with { encode "RAW"; /*variant "FIELDORDER(msb)" */} |