From b2f94c4baa7f4bfdc2fd2b28d19087a2177f3df6 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 19 Jul 2017 20:17:31 +0200 Subject: move lapd to lapdm (it was a mis-nomer) --- lapdm/L1CTL_Test.ttcn | 202 +++++++++++++++++++++++++++++++++++++++ lapdm/LAPDm_RAW_PT.ttcn | 248 ++++++++++++++++++++++++++++++++++++++++++++++++ lapdm/LAPDm_Types.ttcn | 202 +++++++++++++++++++++++++++++++++++++++ lapdm/gen_links.sh | 22 +++++ lapdm/regen_makefile.sh | 9 ++ 5 files changed, 683 insertions(+) create mode 100644 lapdm/L1CTL_Test.ttcn create mode 100644 lapdm/LAPDm_RAW_PT.ttcn create mode 100644 lapdm/LAPDm_Types.ttcn create mode 100755 lapdm/gen_links.sh create mode 100755 lapdm/regen_makefile.sh (limited to 'lapdm') diff --git a/lapdm/L1CTL_Test.ttcn b/lapdm/L1CTL_Test.ttcn new file mode 100644 index 00000000..e780de82 --- /dev/null +++ b/lapdm/L1CTL_Test.ttcn @@ -0,0 +1,202 @@ +module L1CTL_Test { + import from GSM_Types all; + import from Osmocom_Types all; + import from LAPDm_RAW_PT all; + import from LAPDm_Types all; + + type component dummy_CT { + port LAPDm_PT LAPDM; + var lapdm_CT lapdm_component; + }; + + function f_init() runs on dummy_CT { + /* create the LAPDm component */ + lapdm_component := lapdm_CT.create; + /* connect our own LAPDM port to the LAPDM Service Provider of the LAPDm component */ + connect(self:LAPDM, lapdm_component:LAPDM_SP); + /* connect the LAPDm compoent's lower-side port to the system L1CTL port (which is internally + * connected to the Unix Domain Socket test port */ + map(lapdm_component:L1CTL, system:L1CTL); + + /* start the LAPDm parallel component calling it's local function LAPDmStart */ + lapdm_component.start(LAPDmStart()); + } + + /* master function establishing a dedicated radio channel (takes care of RACH/IMM.ASS handling) */ + function f_establish_dcch() runs on dummy_CT { + var BCCH_tune_req tune_req := { arfcn := { false, 871 }, combined_ccch := true }; + var DCCH_establish_req est_req := { ra := 23 }; + + LAPDM.send(tune_req); + LAPDM.send(est_req); + LAPDM.receive(DCCH_establish_res:?); + } + + /* helper function releasing dedicated radio channel physically (no Um signaling!) */ + function f_release_dcch() runs on dummy_CT { + var DCCH_release_req rel_req := {}; + LAPDM.send(rel_req); + } + + template LAPDm_ph_data t_PH_DATA(template GsmSapi sapi, template boolean sacch, template LapdmFrame frame) := { + sacch := sacch, + sapi := sapi, + lapdm := frame + } + /* template for a valid SABM frame */ + template LapdmFrame LAPDm_B_SABM(template GsmSapi sapi, octetstring payload) := { + b := { + addr := tr_LapdmAddr(sapi, false), + ctrl := t_LapdmCtrlSABM(true), + len := lengthof(payload), + m := false, + el := 1, + payload := payload + } + } + + /* template for a valid UA frame */ + template LapdmFrame tr_LAPDm_B_UA(template GsmSapi sapi, template octetstring payload) := { + b := { + addr := tr_LapdmAddr(sapi, false), + ctrl := t_LapdmCtrlUA(true), + len := ?, + m := false, + el := 1, + payload := payload + } + } + + /* template for a valid UA frame */ + template LapdmFrame LAPDm_B_UA(template GsmSapi sapi, octetstring payload) := { + b := { + addr := tr_LapdmAddr(sapi, false), + ctrl := t_LapdmCtrlUA(true), + len := lengthof(payload), + m := false, + el := 1, + payload := payload + } + } + + /* template for a valid UI frame */ + template LapdmFrame LAPDm_B_UI(template GsmSapi sapi, octetstring payload) := { + b := { + addr := tr_LapdmAddr(sapi, true), + ctrl := t_LapdmCtrlUI(false), + len := lengthof(payload), + m := false, + el := 1, + payload := payload + } + } + + function f_test_sabm_results_in_ua(uint8_t sapi, boolean use_sacch, octetstring payload) runs on dummy_CT return boolean { + var LAPDm_ph_data phd; + var boolean result := false; + timer T := 5.0; + + f_establish_dcch(); + LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, payload))); + log("====> expecting ", t_PH_DATA(sapi, use_sacch, LAPDm_B_UA(sapi, payload))); + T.start + alt { + [] LAPDM.receive(t_PH_DATA(?, use_sacch, LAPDm_B_UA(sapi, payload))) { result := true; } + [] LAPDM.receive(t_PH_DATA(?, use_sacch, ?)) -> value phd { log("Other msg on DCH: ", phd); repeat; } + [] LAPDM.receive(t_PH_DATA(?, ?, ?)) -> value phd { log("Other PH-DATA: ", phd); repeat; } + [] T.timeout { } + } + f_release_dcch(); + return result; + } + + testcase TC_sabm_ua_dcch_sapi0() runs on dummy_CT { + f_init(); + if (not f_test_sabm_results_in_ua(0, false, 'FEFE'O)) { + setverdict(fail); + } + setverdict(pass); + } + + testcase TC_sabm_ua_dcch_sapi0_nopayload() runs on dummy_CT { + f_init(); + if (f_test_sabm_results_in_ua(0, false, ''O)) { + setverdict(fail, "Initial SABM/UA must contain L3 payload but BTS accepts without"); + } + setverdict(pass); + } + + testcase TC_sabm_ua_dcch_sapi3() runs on dummy_CT { + f_init(); + if (f_test_sabm_results_in_ua(3, false, 'FEFE'O)) { + setverdict(fail, "Initial SABM/UA must be on SAPI0, but BTS accepts SAPI=3"); + } + setverdict(pass); + } + + testcase TC_sabm_ua_dcch_sapi4() runs on dummy_CT { + f_init(); + if (f_test_sabm_results_in_ua(4, false, 'FEFE'O)) { + setverdict(fail, "Initial SABM/UA must be on SAPI0, but BTS accepts SAPI=4"); + } + setverdict(pass); + } + + testcase TC_sabm_contention() runs on dummy_CT { + var LAPDm_ph_data phd; + const octetstring payload := '0102030405'O; + const GsmSapi sapi := 0; + const boolean use_sacch := false; + timer T := 5.0; + + f_init(); + + f_establish_dcch(); + /* first frame is our real SABM */ + LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, payload))); + /* second frame is a SABM with different payload, which BTS has to ignore according to 8.4.1.4 */ + LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, 'ABCDEF'O))); + log("====> expecting ", t_PH_DATA(sapi, use_sacch, LAPDm_B_UA(sapi, payload))); + T.start + alt { + [] LAPDM.receive(t_PH_DATA(?, use_sacch, LAPDm_B_UA(sapi, payload))) { setverdict(pass); repeat; } + [] LAPDM.receive(t_PH_DATA(?, use_sacch, tr_LAPDm_B_UA(sapi, ?))) { + setverdict(fail, "Second SABM was responded to during contention resolution"); + } + [] LAPDM.receive { repeat }; + [] T.timeout { } + } + f_release_dcch(); + } + + + testcase TC_foo() runs on dummy_CT { +/* + var LapdmFrame lf := valueof(LAPDm_B_UA(0, ''O)); + log("ENC UA: ", enc_LapdmFrame(lf)); + lf := valueof(LAPDm_B_UI(0, ''O)); + log("ENC UI B: ", enc_LapdmFrame(lf)); + log("ENC UI B: ", enc_LapdmFrameB(lf.b)); + + log("DEC UI AF: ", dec_LapdmAddressField('03'O)); +*/ + log("DEC UI CU: ", dec_LapdmCtrlU('03'O)); + log("DEC UI CT: ", dec_LapdmCtrl('03'O)); + + log("DEC UA: ", dec_LapdmFrameB('017301'O)); + log("DEC UI: ", dec_LapdmFrameA('030301'O)); + log("DEC I: ", dec_LapdmFrameA('030001'O)); + log("DEC S: ", dec_LapdmFrameA('030101'O)); + log("DEC: ", dec_LapdmFrameB('030301'O)); + log("DEC: ", dec_LapdmFrameB('0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O)); + } + + control { + execute(TC_foo()); + execute(TC_sabm_ua_dcch_sapi0()); + execute(TC_sabm_ua_dcch_sapi0_nopayload()); + execute(TC_sabm_ua_dcch_sapi3()); + execute(TC_sabm_ua_dcch_sapi4()); + execute(TC_sabm_contention()); + } +} diff --git a/lapdm/LAPDm_RAW_PT.ttcn b/lapdm/LAPDm_RAW_PT.ttcn new file mode 100644 index 00000000..37824d3a --- /dev/null +++ b/lapdm/LAPDm_RAW_PT.ttcn @@ -0,0 +1,248 @@ +/* Test Port that stacks on top of L1CTL test port and performs LAPDm encoding/decoding, so the user can send + * and receive LAPDm frames in decoded TTCN-3 data types. This is particularly useful for sending/receiving + * all kinds of hand-crafted LAPDm frames for testing of the remote LAPDm layer */ +module LAPDm_RAW_PT { + import from GSM_Types all; + import from Osmocom_Types all; + import from L1CTL_Types all; + import from L1CTL_PortType all; + import from LAPDm_Types all; + + /* request to tune to a given ARFCN and start BCCH decoding */ + type record BCCH_tune_req { + Arfcn arfcn, + boolean combined_ccch + } + + /* ask for a dedicated channel to be established */ + type record DCCH_establish_req { + uint8_t ra + } + + type record DCCH_establish_res { + ChannelDescription chan_desc optional, + charstring err optional + } + + type record DCCH_release_req { + } + + /* PH-DATA.ind / PH-DATA.req */ + type record LAPDm_ph_data { + boolean sacch, + GsmSapi sapi, + LapdmFrame lapdm + } + + /* port from our (internal) point of view */ + type port LAPDm_SP_PT message { + in BCCH_tune_req, + DCCH_establish_req, + DCCH_release_req, + LAPDm_ph_data; + out DCCH_establish_res, + LAPDm_ph_data; + } with {extension "internal"}; + + /* port from user (external) point of view */ + type port LAPDm_PT message { + in DCCH_establish_res, + LAPDm_ph_data; + out BCCH_tune_req, + DCCH_establish_req, + DCCH_release_req, + LAPDm_ph_data; + } with {extension "internal"}; + + function LAPDmStart() runs on lapdm_CT { + f_init(); + ScanEvents(); + } + + /* TS 44.004 Figure 5.1 */ + type enumerated ph_state_enum { + PH_STATE_NULL, + PH_STATE_BCH, + PH_STATE_SEARCHING_BCH, + PH_STATE_TUNING_DCH, + PH_STATE_DCH + } + + type component lapdm_CT { + var charstring l1ctl_sock_path := "/tmp/osmocom_l2"; + + /* L1CTL port towards the bottom */ + port L1CTL_PT L1CTL; + /* Port towards L2 */ + port LAPDm_SP_PT LAPDM_SP; + + /* physical layer state */ + var ph_state_enum ph_state := PH_STATE_NULL; + + /* channel description of the currently active DCH */ + var ChannelDescription chan_desc; + }; + + /* wrapper function to log state transitions */ + private function set_ph_state(ph_state_enum new_state) runs on lapdm_CT { + log("PH-STATE ", ph_state, " -> ", new_state); + ph_state := new_state; + } + + private function f_init() runs on lapdm_CT { + L1CTL.send(L1CTL_connect:{path:=l1ctl_sock_path}); + L1CTL.receive(L1CTL_connect_result:{result_code := SUCCESS, err:=omit}); + + L1CTL.send(t_L1ctlResetReq(L1CTL_RES_T_SCHED)); + L1CTL.receive; + set_ph_state(PH_STATE_NULL); + } + + /* release the dedicated radio channel */ + private function f_release_dcch() runs on lapdm_CT { + L1CTL.send(t_L1CTL_DM_REL_REQ(chan_desc.chan_nr)); + set_ph_state(PH_STATE_NULL); + } + + /* tune to given ARFCN and start BCCH/CCCH decoding */ + private function f_tune_bcch(Arfcn arfcn, boolean combined) runs on lapdm_CT { + var L1ctlCcchMode mode := CCCH_MODE_NON_COMBINED; + if (combined) { + mode := CCCH_MODE_COMBINED; + } + + if (ph_state == PH_STATE_DCH) { + /* release any previous DCH */ + f_release_dcch(); + } + + set_ph_state(PH_STATE_SEARCHING_BCH); + + /* send FB/SB req to sync to cell */ + f_L1CTL_FBSB(L1CTL, arfcn, mode); + set_ph_state(PH_STATE_BCH); + } + + /* master function establishing a dedicated radio channel */ + private function f_establish_dcch(uint8_t ra) runs on lapdm_CT { + var ImmediateAssignment imm_ass; + var GsmFrameNumber rach_fn; + + /* send RACH request and obtain FN at which it was sent */ + rach_fn := f_L1CTL_RACH(L1CTL, ra); + //if (not rach_fn) { return; } + + /* wait for receiving matching IMM ASS */ + imm_ass := f_L1CTL_WAIT_IMM_ASS(L1CTL, ra, rach_fn) + //if (not imm_ass) { return; } + set_ph_state(PH_STATE_TUNING_DCH); + + /* store/save channel description */ + chan_desc := imm_ass.chan_desc; + + /* send DM_EST_REQ */ + f_L1CTL_DM_EST_REQ_IA(L1CTL, imm_ass); + set_ph_state(PH_STATE_DCH); + } + + function ScanEvents() runs on lapdm_CT { + var L1ctlDlMessage dl; + var BCCH_tune_req bt; + var LAPDm_ph_data lpd; + var DCCH_establish_req est_req; + var DCCH_establish_res est_res; + + while (true) { + if (ph_state == PH_STATE_NULL) { + alt { + [] LAPDM_SP.receive(BCCH_tune_req:?) -> value bt { + f_tune_bcch(bt.arfcn, bt.combined_ccch); + } + + [] LAPDM_SP.receive {} + [] L1CTL.receive {} + + } + } else if (ph_state == PH_STATE_BCH or ph_state == PH_STATE_SEARCHING_BCH) { + alt { + [] LAPDM_SP.receive(BCCH_tune_req:?) -> value bt { + f_tune_bcch(bt.arfcn, bt.combined_ccch); + } + + /* forward CCCH SAPI from L1CTL to User */ + [] L1CTL.receive(t_L1CTL_DATA_IND(t_RslChanNr_BCCH(0))) -> value dl { + lpd.sacch := false; + lpd.sapi := 0; + lpd.lapdm.bbis := dec_LapdmFrameBbis(dl.payload.data_ind.payload); + LAPDM_SP.send(lpd); + } + + /* forward BCCH SAPI from L1CTL to User */ + [] L1CTL.receive(t_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0))) -> value dl { + lpd.sacch := false; + lpd.sapi := 0; + lpd.lapdm.bbis := dec_LapdmFrameBbis(dl.payload.data_ind.payload); + LAPDM_SP.send(lpd); + } + + /* Establish dedicated channel */ + [] LAPDM_SP.receive(DCCH_establish_req:?) -> value est_req { + var DCCH_establish_res res; + f_establish_dcch(est_req.ra); + if (ph_state == PH_STATE_DCH) { + res := { chan_desc, omit }; + } else { + res := { omit, "Unable to esetablish DCCH" }; + } + LAPDM_SP.send(res); + } + + [] LAPDM_SP.receive {} + [] L1CTL.receive {} + + } + + } else if (ph_state == PH_STATE_TUNING_DCH or ph_state == PH_STATE_DCH) { + alt { + + /* decode any received DATA frames for the dedicated channel and pass them up */ + [] L1CTL.receive(t_L1CTL_DATA_IND(chan_desc.chan_nr)) -> value dl { + if (dl.dl_info.link_id.c == SACCH) { + lpd.sacch := true; + /* FIXME: how to deal with UI frames in B4 format (lo length!) */ + } else { + lpd.sacch := false; + } + lpd.sapi := dl.dl_info.link_id.sapi; + lpd.lapdm.b := dec_LapdmFrameB(dl.payload.data_ind.payload); + LAPDM_SP.send(lpd); + } + + /* encode any LAPDm record from user and pass it on to L1CTL */ + [] LAPDM_SP.receive(LAPDm_ph_data:?) -> value lpd { + var octetstring buf; + var RslLinkId link_id; + if (lpd.sacch) { + link_id := valueof(ts_RslLinkID_SACCH(lpd.sapi)); + } else { + link_id := valueof(ts_RslLinkID_DCCH(lpd.sapi)); + } + buf := enc_LapdmFrame(lpd.lapdm); + L1CTL.send(t_L1CTL_DATA_REQ(chan_desc.chan_nr, link_id, buf)); + } + + /* Release dedicated channel */ + [] LAPDM_SP.receive(DCCH_release_req:?) { + /* go back to BCCH */ + f_release_dcch(); + } + + [] LAPDM_SP.receive {} + [] L1CTL.receive {} + + + } + } + } /* while (1) */ + } +} diff --git a/lapdm/LAPDm_Types.ttcn b/lapdm/LAPDm_Types.ttcn new file mode 100644 index 00000000..988e015b --- /dev/null +++ b/lapdm/LAPDm_Types.ttcn @@ -0,0 +1,202 @@ +/* LAPDm definitiona according to 3GPP TS 44.006 */ +/* (C) 2017 bh Harald Welte */ +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, + uint3_t n_s, + boolean p, + uint3_t n_r + } with { variant "FIELDORDER(lsb)" }; + + type record LapdmCtrlS { + BIT2 spare, + LapdmSBits s, + boolean p_f, + uint3_t n_r + } with { variant "FIELDORDER(lsb)" }; + + type record LapdmCtrlU { + BIT2 spare, + 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)" */} diff --git a/lapdm/gen_links.sh b/lapdm/gen_links.sh new file mode 100755 index 00000000..d8497511 --- /dev/null +++ b/lapdm/gen_links.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +BASEDIR=~/projects/git + +gen_links() { + DIR=$1 + FILES=$* + for f in $FILES; do + echo "Linking $f" + ln -sf $DIR/$f $f + done +} + +DIR=$BASEDIR/titan.TestPorts.UNIX_DOMAIN_SOCKETasp/src +FILES="UD_PT.cc UD_PT.hh UD_PortType.ttcn UD_Types.ttcn" +gen_links $DIR $FILES + + + +DIR=../library +FILES="General_Types.ttcn GSM_Types.ttcn Osmocom_Types.ttcn L1CTL_PortType.ttcn L1CTL_Types.ttcn" +gen_links $DIR $FILES diff --git a/lapdm/regen_makefile.sh b/lapdm/regen_makefile.sh new file mode 100755 index 00000000..8d321ac4 --- /dev/null +++ b/lapdm/regen_makefile.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +FILES="*.ttcn UD_PT.cc UD_PT.hh" + +ttcn3_makefilegen -f L1CTL_Test.ttcn $FILES +sed -i -e 's/# TTCN3_DIR = /TTCN3_DIR = \/usr/' Makefile +sed -i -e 's/LDFLAGS = /LDFLAGS = -L \/usr\/lib\/titan `pkg-config --libs libnetfilter_conntrack`/' Makefile +sed -i -e 's/TTCN3_LIB = ttcn3-parallel/TTCN3_LIB = ttcn3/' Makefile +sed -i -e 's/CPPFLAGS = -D$(PLATFORM) -I$(TTCN3_DIR)\/include/CPPFLAGS = -D$(PLATFORM) -I$(TTCN3_DIR)\/include -I\/usr\/include\/titan/' Makefile -- cgit v1.2.3