diff --git a/lapd/LAPD_Primitives.ttcn b/lapd/LAPD_Primitives.ttcn new file mode 100644 index 000000000..e6c8f3609 --- /dev/null +++ b/lapd/LAPD_Primitives.ttcn @@ -0,0 +1,112 @@ +module LAPD_Primitives { + +import from LAPD_Types all; + +type enumerated PrimOperation { + REQUEST, + RESPONSE, + INDICATION, + CONFIRM +}; + +type record LAPD_DL_Prim { + LapdTei tei, + LapdSapi sapi, + LAPD_DL primitive, + PrimOperation operation +} +type union LAPD_DL { + LapdDlEstablish dl_establish, + LapdDlRelease dl_release, + LapdDlData dl_data, + LapdDlUnitData dl_unitdata +}; +type record LapdDlEstablish { +}; +type record LapdDlRelease { +}; +type record LapdDlData { + octetstring payload +}; +type record LapdDlUnitData { + octetstring payload +}; + +type record LAPD_MDL_Prim { + LAPD_MDL primitive, + PrimOperation operation +} +type union LAPD_MDL { + LapdMdlAssign mdl_assign, + LapdMdlRemove mdl_remove, + LapdMdlError mdl_error, + LapdMdlUnitData mdl_unitdata, + LapdMdlXid mdl_xid +}; +type record LapdMdlAssign { + LapdTei tei + //ces +}; +type record LapdMdlRemove { + LapdTei tei + //ces +}; +type record LapdMdlError { + charstring reason +}; +type record LapdMdlUnitData { + octetstring lm_pdu +}; +type record LapdMdlXid { + octetstring cm_pdu +}; + +type record LAPD_PH_Prim { + LAPD_PH primitive, + PrimOperation operation +} +type union LAPD_PH { + LapdPhData ph_data, + LapdPhActivate ph_activate, + LapdPhDeactivate ph_deactivate +}; +type record LapdPhData { + // priority + octetstring data +}; +type record LapdPhActivate { +} +type record LapdPhDeactivate { +} + +type record LAPD_MPH_Prim { + Lapd_MPH primitive, + PrimOperation operation +}; +type union Lapd_MPH { + LapdMphActivate mph_activate, + LapdMphDeactivate mph_deactivate, + LapdMphInformation mph_information +}; +type record LapdMphActivate { +}; +type record LapdMphDeactivate { +}; +type record LapdMphInformation { + // connected/disconnected +}; + +type union LAPD_Primitive { + LAPD_DL_Prim dl, + LAPD_MDL_Prim mdl, + LAPD_PH_Prim ph, + LAPD_MPH_Prim mph +}; + +external function f_enc_LAPD_Primitive(in LAPD_Primitive inp) return octetstring + with { extension "prototype(convert) encode(JSON)" } +external function f_dec_LAPD_Primitive(in octetstring inp) return LAPD_Primitive + with { extension "prototype(convert) decode(JSON)" } + + +} with { encode "JSON" } diff --git a/lapd/LAPD_Tests.ttcn b/lapd/LAPD_Tests.ttcn new file mode 100644 index 000000000..74e95c5f8 --- /dev/null +++ b/lapd/LAPD_Tests.ttcn @@ -0,0 +1,17 @@ +module LAPD_Tests { + +import from LAPD_Types all; + +type component test_CT { +}; + + +testcase TC_selftest() runs on test_CT { + var LapdAddressField addr; + + addr := { sapi := 62, c_r := true, ea0 := false, tei := 55, ea1 := true }; + log(enc_LapdAddressField(addr)); +} + + +} diff --git a/lapd/RLAPD_CodecPort.ttcn b/lapd/RLAPD_CodecPort.ttcn new file mode 100644 index 000000000..e9f4c6327 --- /dev/null +++ b/lapd/RLAPD_CodecPort.ttcn @@ -0,0 +1,64 @@ +module RLAPD_CodecPort { + +/* Simple RLAPD Codec Port, translating between raw TCP octetstring payload + * towards the IPL4asp port provider, and RLAPD primitives + * which carry the decoded RLAPD data types as payload. + * + * (C) 2020 by Harald Welte + * All rights reserved. + * + * Released under the terms of GNU General Public License, Version 2 or + * (at your option) any later version. + */ + + +import from IPL4asp_PortType all; +import from IPL4asp_Types all; +import from LAPD_Primitives all; + +type record RLAPD_RecvFrom { + ConnectionId connId, + LAPD_Primitive msg +} + +type record RLAPD_Send { + ConnectionId connId, + LAPD_Primitive msg +} + +template (value) RLAPD_Send ts_RLAPD_Send(ConnectionId conn_id, template (value) LAPD_Primitive msg) := { + connId := conn_id, + msg := msg +} + +template RLAPD_RecvFrom tr_RLAPD_Recv(template ConnectionId conn_id, template LAPD_Primitive msg) := { + connId := conn_id, + msg := msg +} + +private function IPL4_to_RLAPD_RecvFrom(in ASP_RecvFrom pin, out RLAPD_RecvFrom pout) { + pout.connId := pin.connId; + pout.msg := f_dec_LAPD_Primitive(pin.msg); +} with { extension "prototype(fast)" } + +private function RLAPD_to_IPL4_Send(in RLAPD_Send pin, out ASP_Send pout) { + pout.connId := pin.connId; + pout.proto := { sctp := {} }; + pout.msg := f_enc_LAPD_Primitive(pin.msg); +} with { extension "prototype(fast)" } + +type port RLAPD_CODEC_PT message { + out RLAPD_Send; + in RLAPD_RecvFrom, + ASP_ConnId_ReadyToRelease, + ASP_Event; +} with { extension "user IPL4asp_PT + out(RLAPD_Send -> ASP_Send: function(RLAPD_to_IPL4_Send)) + in(ASP_RecvFrom -> RLAPD_RecvFrom: function(IPL4_to_RLAPD_RecvFrom); + ASP_ConnId_ReadyToRelease -> ASP_ConnId_ReadyToRelease: simple; + ASP_Event -> ASP_Event: simple)" +} + + + +} diff --git a/lapd/RLAPD_CodecPort_CtrlFunct.ttcn b/lapd/RLAPD_CodecPort_CtrlFunct.ttcn new file mode 100644 index 000000000..a0280fb2b --- /dev/null +++ b/lapd/RLAPD_CodecPort_CtrlFunct.ttcn @@ -0,0 +1,52 @@ +module RLAPD_CodecPort_CtrlFunct { + + import from RLAPD_CodecPort all; + import from IPL4asp_Types all; + + external function f_IPL4_listen( + inout RLAPD_CODEC_PT portRef, + in HostName locName, + in PortNumber locPort, + in ProtoTuple proto, + in OptionList options := {} + ) return Result; + + external function f_IPL4_connect( + inout RLAPD_CODEC_PT portRef, + in HostName remName, + in PortNumber remPort, + in HostName locName, + in PortNumber locPort, + in ConnectionId connId, + in ProtoTuple proto, + in OptionList options := {} + ) return Result; + + external function f_IPL4_close( + inout RLAPD_CODEC_PT portRef, + in ConnectionId id, + in ProtoTuple proto := { unspecified := {} } + ) return Result; + + external function f_IPL4_setUserData( + inout RLAPD_CODEC_PT portRef, + in ConnectionId id, + in UserData userData + ) return Result; + + external function f_IPL4_getUserData( + inout RLAPD_CODEC_PT portRef, + in ConnectionId id, + out UserData userData + ) return Result; + + external function f_IPL4_setGetMsgLen( + inout RLAPD_CODEC_PT portRef, + in ConnectionId id, + inout f_IPL4_getMsgLen f, + in ro_integer msgLenArgs + ); + + +} + diff --git a/lapd/RLAPD_CodecPort_CtrlFunctDef.cc b/lapd/RLAPD_CodecPort_CtrlFunctDef.cc new file mode 100644 index 000000000..8c1efe9a1 --- /dev/null +++ b/lapd/RLAPD_CodecPort_CtrlFunctDef.cc @@ -0,0 +1,66 @@ +#include "IPL4asp_PortType.hh" +#include "RLAPD_CodecPort.hh" +#include "IPL4asp_PT.hh" + +namespace RLAPD__CodecPort__CtrlFunct { + + IPL4asp__Types::Result f__IPL4__listen( + RLAPD__CodecPort::RLAPD__CODEC__PT& portRef, + const IPL4asp__Types::HostName& locName, + const IPL4asp__Types::PortNumber& locPort, + const IPL4asp__Types::ProtoTuple& proto, + const IPL4asp__Types::OptionList& options) + { + return f__IPL4__PROVIDER__listen(portRef, locName, locPort, proto, options); + } + + IPL4asp__Types::Result f__IPL4__connect( + RLAPD__CodecPort::RLAPD__CODEC__PT& portRef, + const IPL4asp__Types::HostName& remName, + const IPL4asp__Types::PortNumber& remPort, + const IPL4asp__Types::HostName& locName, + const IPL4asp__Types::PortNumber& locPort, + const IPL4asp__Types::ConnectionId& connId, + const IPL4asp__Types::ProtoTuple& proto, + const IPL4asp__Types::OptionList& options) + { + return f__IPL4__PROVIDER__connect(portRef, remName, remPort, + locName, locPort, connId, proto, options); + } + + IPL4asp__Types::Result f__IPL4__close( + RLAPD__CodecPort::RLAPD__CODEC__PT& portRef, + const IPL4asp__Types::ConnectionId& connId, + const IPL4asp__Types::ProtoTuple& proto) + { + return f__IPL4__PROVIDER__close(portRef, connId, proto); + } + + IPL4asp__Types::Result f__IPL4__setUserData( + RLAPD__CodecPort::RLAPD__CODEC__PT& portRef, + const IPL4asp__Types::ConnectionId& connId, + const IPL4asp__Types::UserData& userData) + { + return f__IPL4__PROVIDER__setUserData(portRef, connId, userData); + } + + IPL4asp__Types::Result f__IPL4__getUserData( + RLAPD__CodecPort::RLAPD__CODEC__PT& portRef, + const IPL4asp__Types::ConnectionId& connId, + IPL4asp__Types::UserData& userData) + { + return f__IPL4__PROVIDER__getUserData(portRef, connId, userData); + } + + void f__IPL4__setGetMsgLen( + RLAPD__CodecPort::RLAPD__CODEC__PT& portRef, + const IPL4asp__Types::ConnectionId& connId, + Socket__API__Definitions::f__getMsgLen& f, + const Socket__API__Definitions::ro__integer& msgLenArgs) + { + return f__IPL4__PROVIDER__setGetMsgLen(portRef, connId, f, msgLenArgs); + } + + +} + diff --git a/lapd/gen_links.sh b/lapd/gen_links.sh new file mode 100755 index 000000000..ecdf2e455 --- /dev/null +++ b/lapd/gen_links.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +BASEDIR=../deps + +. ../gen_links.sh.inc + +DIR=$BASEDIR/titan.Libraries.TCCUsefulFunctions/src +FILES="TCCInterface_Functions.ttcn TCCConversion_Functions.ttcn TCCConversion.cc TCCInterface.cc TCCInterface_ip.h" +gen_links $DIR $FILES + +DIR=$BASEDIR/titan.TestPorts.Common_Components.Socket-API/src +FILES="Socket_API_Definitions.ttcn" +gen_links $DIR $FILES + +DIR=$BASEDIR/titan.TestPorts.IPL4asp/src +FILES="IPL4asp_Functions.ttcn IPL4asp_PT.cc IPL4asp_PT.hh IPL4asp_PortType.ttcn IPL4asp_Types.ttcn IPL4asp_discovery.cc IPL4asp_protocol_L234.hh" +gen_links $DIR $FILES + +DIR=../library +FILES="Misc_Helpers.ttcn General_Types.ttcn Osmocom_Types.ttcn LAPD_Types.ttcn " +gen_links $DIR $FILES + +ignore_pp_results diff --git a/lapd/regen_makefile.sh b/lapd/regen_makefile.sh new file mode 100755 index 000000000..6f8af367c --- /dev/null +++ b/lapd/regen_makefile.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +FILES="*.ttcn IPL4asp_PT.cc IPL4asp_discovery.cc TCCConversion.cc TCCInterface.cc " +FILES+="RLAPD_CodecPort_CtrlFunctDef.cc " + +../regen-makefile.sh LAPD_Tests.ttcn $FILES diff --git a/library/LAPD_Types.ttcn b/library/LAPD_Types.ttcn new file mode 100644 index 000000000..6e6cc7b99 --- /dev/null +++ b/library/LAPD_Types.ttcn @@ -0,0 +1,413 @@ +/* LAPDm definitions according to ITU-T Q.921 + * (C) 2017-2020 by Harald Welte + * All rights reserved. + * + * Released under the terms of GNU General Public License, Version 2 or + * (at your option) any later version. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +module LAPD_Types { + +import from General_Types all; +import from Osmocom_Types all; + +type uint6_t LapdSapi; +type uint7_t LapdTei; +type BIT2 LapdSBits; +type BIT3 LapdUBits; +type BIT2 LapdU2Bits; + +/* Section 3.3.2 / Table 1*/ +const boolean cr_UO_CMD := false; +const boolean cr_UO_RSP := true; +const boolean cr_UT_CMD := true; +const boolean cr_UT_RSP := false; + +/* Figure 5 */ +type record LapdAddressField { + LapdSapi sapi, + boolean c_r, + boolean ea0 (false), + LapdTei tei, + boolean ea1 (true) +} with { variant "FIELDORDER(msb)" }; + +template (present) LapdAddressField +tr_LapdAddr(template (present) LapdTei tei := ?, + template (present) LapdSapi sapi := ?, + template (present) boolean c_r) := { + sapi := sapi, + c_r := c_r, + ea0 := false, + tei := tei, + ea1 := true +}; + +template (value) LapdAddressField +ts_LapdAddr(template (value) LapdTei tei, + template (value) LapdSapi sapi, boolean c_r) := { + sapi := sapi, + c_r := c_r, + ea0 := false, + tei := tei, + ea1 := true +}; + +/* Table 4 */ +type record LapdCtrlI { + uint7_t n_s, + BIT1 spare ('0'B), + uint7_t n_r, + boolean p +} with { variant "FIELDORDER(msb)" }; + +type record LapdCtrlS { + BIT4 reserved ('0000'B), + LapdSBits s, + BIT2 spare ('01'B), + uint8_t n_r, + boolean p_f +} with { variant "FIELDORDER(msb)" }; + +type record LapdCtrlU { + LapdUBits u, + boolean p_f, + LapdU2Bits u2, + BIT2 spare ('11'B) +} with { variant "FIELDORDER(msb)" }; + +type union LapdCtrl { + LapdCtrlS s, + LapdCtrlU u, + LapdCtrlI i, + uint8_t other +} with { variant "TAG(u, spare = '11'B; + s, spare = '01'B; + i, spare = '0'B; + other, OTHERWISE)" }; + /* )" }; */ + + +template (present) LapdCtrl tr_LapdCtrlU := { + u := { u := ?, p_f := ?, u2 := ?, spare := '11'B } +}; + +template (present) LapdCtrl tr_LapdCtrlS := { + s := { reserved := '0000'B, s := ?, spare := '01'B, n_r := ?, p_f := ? } +}; + +template (present) LapdCtrl +tr_LapdCtrlI(template (present) uint7_t nr, template (present) uint7_t ns, + template (present) boolean p) := { + i := { n_s := ns, spare := '0'B, n_r := nr, p := p } +}; +template (value) LapdCtrl +ts_LapdCtrlI(uint7_t nr, uint7_t ns, boolean p) := { + i := { n_s := ns, spare := '0'B, n_r := nr, p := p } +}; + +template (present) LapdCtrl +tr_LapdCtrlRR(template (present) uint7_t nr, template (present) boolean pf) +modifies tr_LapdCtrlS := { + s := { s := '00'B, n_r := nr, p_f := pf } +}; +template (value) LapdCtrl ts_LapdCtrlRR(uint7_t nr, boolean pf) := { + s := { reserved := '0000'B, s := '00'B, spare := '01'B, n_r := nr, p_f := pf } +}; + +template (present) LapdCtrl +tr_LapdCtrlRNR(template (present) uint7_t nr, template (present) boolean pf) +modifies tr_LapdCtrlS := { + s := { s := '01'B, n_r := nr, p_f := pf } +}; + +template (present) LapdCtrl +tr_LapdCtrlREJ(template (present) uint7_t nr, template (present) boolean pf) +modifies tr_LapdCtrlS := { + s := { s := '10'B, n_r := nr, p_f := pf } +}; +template (value) LapdCtrl +ts_LapdCtrlREJ(uint7_t nr, boolean pf) := { + s := { reserved := '0000'B, s := '10'B, spare := '01'B, n_r := nr, p_f := pf } +}; + +template (present) LapdCtrl +tr_LapdCtrlSABM(template (present) boolean p) := { + u := { u := '001'B, p_f := p, u2 := '11'B, spare := '11'B } +}; +template (value) LapdCtrl +ts_LapdCtrlSABM(boolean p) := { + u := { u := '001'B, p_f := p, u2 := '11'B, spare := '11'B } +}; + +template (present) LapdCtrl +tr_LapdCtrlDM(template (present) boolean f) := { + u := { u := '000'B, p_f := f, u2 := '11'B, spare := '11'B } +}; +template (value) LapdCtrl +ts_LapdCtrlDM(boolean f) := { + u := { u := '000'B, p_f := f, u2 := '11'B, spare := '11'B } +}; + +template (present) LapdCtrl +tr_LapdCtrlUI(template (present) boolean p := false) := { + u := { u := '000'B, p_f := p, u2 := '00'B, spare := '11'B } +}; +template (value) LapdCtrl +ts_LapdCtrlUI(boolean p := false) := { + u := { u := '000'B, p_f := p, u2 := '00'B, spare := '11'B } +}; + +template (present) LapdCtrl +tr_LapdCtrlDISC(template (present) boolean p) := { + u := { u := '010'B, p_f := p, u2 := '00'B, spare := '11'B } +}; +template (value) LapdCtrl +ts_LapdCtrlDISC(boolean p) := { + u := { u := '010'B, p_f := p, u2 := '00'B, spare := '11'B } +}; + +template (present) LapdCtrl +tr_LapdCtrlUA(template (present) boolean f) modifies tr_LapdCtrlU := { + u := { u := '011'B, p_f := f, u2 := '00'B, spare := '11'B } +}; +template (value) LapdCtrl +ts_LapdCtrlUA(boolean f) := { + u := { u := '011'B, p_f := f, u2 := '00'B, spare := '11'B } +}; + +template (present) LapdCtrl +tr_LapdCtrlFRMR(template (present) boolean f) modifies tr_LapdCtrlU := { + u := { u := '100'B, p_f := f, u2 := '01'B, spare := '11'B } +}; +template (value) LapdCtrl +ts_LapdCtrlFRMR(boolean f) := { + u := { u := '100'B, p_f := f, u2 := '01'B, spare := '11'B } +}; + +template (present) LapdCtrl +tr_LapdCtrlXID(template (present) boolean p_f) modifies tr_LapdCtrlU := { + u := { u := '101'B, p_f := p_f, u2 := '11'B, spare := '11'B } +}; +template (value) LapdCtrl +ts_LapdCtrlXID(boolean p_f) := { + u := { u := '101'B, p_f := p_f, u2 := '11'B, spare := '11'B } +}; + + +external function dec_LapdAddressField(in octetstring stream) return LapdAddressField + with { extension "prototype(convert) decode(RAW)" }; +external function enc_LapdAddressField(in LapdAddressField f) return octetstring + with { extension "prototype(convert) encode(RAW)" }; + +external function dec_LapdCtrl(in octetstring stream) return LapdCtrl + with { extension "prototype(convert) decode(RAW)" }; + +external function dec_LapdCtrlU(in octetstring stream) return LapdCtrlU + with { extension "prototype(convert) decode(RAW)" }; + + +type record LapdFrame { + LapdAddressField addr, + LapdCtrl ctrl, + octetstring payload // zero-length in Frame A +} with { variant "FIELDORDER(msb)" }; + +external function enc_LapdFrame(in LapdFrame si) return octetstring + with { extension "prototype(convert) encode(RAW)" }; +external function dec_LapdFrame(in octetstring stream) return LapdFrame + with { extension "prototype(convert) decode(RAW)" }; + +template (value) LapdFrame +ts_LAPD_SABM(LapdTei tei, LapdSapi sapi, boolean c_r, boolean p, octetstring l3) := { + addr := ts_LapdAddr(tei, sapi, c_r), + ctrl := ts_LapdCtrlSABM(p), + payload := l3 +} +template (present) LapdFrame +tr_LAPD_SABM(template (present) LapdTei tei, template (present) LapdSapi sapi, + template (present) boolean c_r, template (present) boolean p, + template (present) octetstring l3) := { + addr := tr_LapdAddr(tei, sapi, c_r), + ctrl := tr_LapdCtrlSABM(p), + payload := l3 +} + +template (value) LapdFrame +ts_LAPD_UA(LapdTei tei, LapdSapi sapi, boolean c_r, boolean f, octetstring l3) := { + addr := ts_LapdAddr(tei, sapi, c_r), + ctrl := ts_LapdCtrlUA(f), + payload := l3 +} +template (present) LapdFrame +tr_LAPD_UA(template (present) LapdTei tei, template (present) LapdSapi sapi, + template (present) boolean c_r, template (present) boolean f, + template (present) octetstring l3) := { + addr := tr_LapdAddr(tei, sapi, c_r), + ctrl := tr_LapdCtrlUA(f), + payload := l3 +} + +template (value) LapdFrame +ts_LAPD_DM(LapdTei tei, LapdSapi sapi, boolean c_r, boolean f) := { + addr := ts_LapdAddr(tei, sapi, c_r), + ctrl := ts_LapdCtrlDM(f), + payload := ''O +} +template (present) LapdFrame +tr_LAPD_DM(template (present) LapdTei tei, template (present) LapdSapi sapi, + template (present) boolean c_r, template (present) boolean f) := { + addr := tr_LapdAddr(tei, sapi, c_r), + ctrl := tr_LapdCtrlDM(f), + payload := ''O +} + +template (value) LapdFrame +ts_LAPD_DISC(LapdTei tei, LapdSapi sapi, boolean c_r, boolean p) := { + addr := ts_LapdAddr(tei, sapi, c_r), + ctrl := ts_LapdCtrlDISC(p), + payload := ''O +} +template (present) LapdFrame +tr_LAPD_DISC(template (present) LapdTei tei, template (present) LapdSapi sapi, + template (present) boolean c_r, template (present) boolean p) := { + addr := tr_LapdAddr(tei, sapi, c_r), + ctrl := tr_LapdCtrlDISC(p), + payload := ''O +} + +template (value) LapdFrame +ts_LAPD_UI(LapdTei tei, LapdSapi sapi, boolean c_r, octetstring l3) := { + addr := ts_LapdAddr(tei, sapi, c_r), + ctrl := ts_LapdCtrlUI, + payload := l3 +} +template (present) LapdFrame +tr_LAPD_UI(template (present) LapdTei tei, template (present) LapdSapi sapi, + template (present) boolean c_r, template (present) octetstring l3) := { + addr := tr_LapdAddr(tei, sapi, c_r), + ctrl := tr_LapdCtrlUI, + payload := l3 +} + +template (value) LapdFrame +ts_LAPD_I(LapdTei tei, LapdSapi sapi, boolean c_r, boolean p, uint7_t nr, + uint7_t ns, octetstring l3, boolean m := false) := { + addr := ts_LapdAddr(tei, sapi, c_r), + ctrl := ts_LapdCtrlI(nr, ns, p), + payload := l3 +} +template (present) LapdFrame +tr_LAPD_I(template (present) LapdTei tei, template (present) LapdSapi sapi, + template (present) boolean c_r, template (present) boolean p, + template (present) uint7_t nr, template (present) uint7_t ns, + template (present) octetstring l3, template (present) boolean m := false) := { + addr := tr_LapdAddr(tei, sapi, c_r), + ctrl := tr_LapdCtrlI(nr, ns, p), + payload := l3 +} + +template (value) LapdFrame +ts_LAPD_RR(LapdTei tei, LapdSapi sapi, boolean c_r, boolean p, uint7_t nr) := { + addr := ts_LapdAddr(tei, sapi, c_r), + ctrl := ts_LapdCtrlRR(nr, p), + payload := ''O +} +template (present) LapdFrame +tr_LAPD_RR(template (present) LapdTei tei, template (present) LapdSapi sapi, + template (present) boolean c_r, template (present) boolean p, + template (present) uint7_t nr) := { + addr := tr_LapdAddr(tei, sapi, c_r), + ctrl := tr_LapdCtrlRR(nr, p), + payload := ''O +} + +template (value) LapdFrame ts_LAPD_REJ(LapdTei tei, LapdSapi sapi, boolean c_r, + boolean p, uint7_t nr) := { + addr := ts_LapdAddr(tei, sapi, c_r), + ctrl := ts_LapdCtrlREJ(nr, p), + payload := ''O +} +template (present) LapdFrame +tr_LAPD_REJ(template (present) LapdTei tei, template (present) LapdSapi sapi, + template (present) boolean c_r, template (present) boolean p, + template (present) uint7_t nr) := { + addr := tr_LapdAddr(tei, sapi, c_r), + ctrl := tr_LapdCtrlREJ(nr, p), + payload := ''O +} + + +/* Table 8/Q.921 */ +type enumerated TeiMgmtMsgType { + IDENTITY_REQUEST ('00000001'B), + IDENTITY_ASSIGNED ('00000010'B), + IDENTITY_DENIED ('00000011'B), + IDENTITY_CHECK_REQ ('00000100'B), + IDENTITY_CHECK_RESP ('00000101'B), + IDENTITY_REMOVE ('00000110'B), + IDENTITY_VERIFY ('00000111'B) +} with { variant "FIELDLENGTH(8)" }; +type record TeiMgmtMsg { + BIT8 me_id ('00001111'B), /* management entity identifier */ + uint16_t ri, /* reference number */ + TeiMgmtMsgType msg_type, + uint7_t ai, + BIT1 e +}; + +template (value) TeiMgmtMsg ts_TEI(TeiMgmtMsgType msgt, uint16_t ri, uint7_t ai) := { + me_id := '00001111'B, + ri := ri, + msg_type := msgt, + ai := ai, + e := '1'B +} + +external function enc_TeiMgmtMsg(in TeiMgmtMsg si) return octetstring + with { extension "prototype(convert) encode(RAW)" }; +external function dec_TeiMgmtMsg(in octetstring stream) return TeiMgmtMsg + with { extension "prototype(convert) decode(RAW)" }; + +template (value) TeiMgmtMsg +ts_TEI_IdRequest(uint16_t ri, uint7_t ai) := ts_TEI(IDENTITY_REQUEST, ri, ai); + +template (value) TeiMgmtMsg +ts_TEI_IdAssigned(uint16_t ri, uint7_t ai) := ts_TEI(IDENTITY_ASSIGNED, ri, ai); + +template (value) TeiMgmtMsg +ts_TEI_IdDenied(uint16_t ri, uint7_t ai) := ts_TEI(IDENTITY_DENIED, ri, ai); + +template (value) TeiMgmtMsg +ts_TEI_IdCheckReq(uint16_t ri, uint7_t ai) := ts_TEI(IDENTITY_CHECK_REQ, ri, ai); + +template (value) TeiMgmtMsg +ts_TEI_IdCheckResp(uint16_t ri, uint7_t ai) := ts_TEI(IDENTITY_CHECK_RESP, ri, ai); + +template (value) TeiMgmtMsg +ts_TEI_IdRemove(uint16_t ri, uint7_t ai) := ts_TEI(IDENTITY_REMOVE, ri, ai); + +template (value) TeiMgmtMsg +ts_TEI_IdVerify(uint16_t ri, uint7_t ai) := ts_TEI(IDENTITY_VERIFY, ri, ai); + + +/* Q.921bis Name:ID_Rmv */ +template (present) LapdFrame +tr_ID_Rmv(template (present) LapdTei tei) := { + addr := ts_LapdAddr(tei := 127, sapi := 63, c_r := true), + ctrl := ts_LapdCtrlUI(p := false) +} + +/* Q.921bis Name:ID_Ver */ +template (present) LapdFrame +tr_ID_Ver(template (present) LapdTei tei) := { + addr := ts_LapdAddr(tei := 127, sapi := 63, c_r := true), + ctrl := ts_LapdCtrlUI(p := false) +} + + + + +} with { encode "RAW"; /*variant "FIELDORDER(msb)" */}