Add new LAPDm RAW port
This is a Test Component which sits on top of L1CTL (which in turn is on top of the Unix Domain Socket Test Porrt). It performs LAPDm message encoding/decoding, so we can use the regular send() / receive() methods and associated template matching to send/receive/match LAPDm in a comfortable way.
This commit is contained in:
parent
cb5d1fb2ee
commit
d4ba7ff93e
|
@ -1,119 +1,164 @@
|
|||
module L1CTL_Test {
|
||||
import from GSM_Types all;
|
||||
import from Osmocom_Types all;
|
||||
import from L1CTL_Types all;
|
||||
import from L1CTL_PortType all;
|
||||
import from LAPDm_RAW_PT all;
|
||||
import from LAPDm_Types all;
|
||||
|
||||
const octetstring c_ul_param_req := '1300000000000000001d0000'O;
|
||||
const octetstring c_ul_data_req := '060a0128284018001d000103490615004001c0000000000000000000000000'O;
|
||||
const octetstring c_ul_ccch_mode_req := '1000000002000000'O;
|
||||
const octetstring c_ul_reset_req := '0d00000002000000'O;
|
||||
const octetstring c_ul_dm_est_req := '050000002800000007000367000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005'O;
|
||||
const octetstring c_ul_rach_req := '040000000000000012010008'O;
|
||||
|
||||
const octetstring c_dl_data_ind := '03000000900003670015f5613f3f00002d063f0328e36712ead000002b2b2b2b2b2b2b2b2b2b2b'O;
|
||||
|
||||
type component dummy_CT {
|
||||
var charstring l1ctl_sock_path := "/tmp/osmocom_l2";
|
||||
port L1CTL_PT L1CTL;
|
||||
var ChannelDescription chan_desc;
|
||||
port LAPDm_PT LAPDM;
|
||||
var lapdm_CT lapdm_component;
|
||||
};
|
||||
|
||||
|
||||
function f_init() runs on dummy_CT {
|
||||
map(self:L1CTL, system:L1CTL);
|
||||
L1CTL.send(L1CTL_connect:{path:=l1ctl_sock_path});
|
||||
L1CTL.receive(L1CTL_connect_result:{result_code := SUCCESS, err:=omit});
|
||||
/* 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);
|
||||
|
||||
L1CTL.send(t_L1ctlResetReq(L1CTL_RES_T_SCHED));
|
||||
L1CTL.receive;
|
||||
/* start the LAPDm parallel component calling it's local function LAPDmStart */
|
||||
lapdm_component.start(LAPDmStart());
|
||||
}
|
||||
|
||||
/* a very ppor man's job to check if we can actually still decode the L1CTL binary messages */
|
||||
testcase TC_selftest() runs on dummy_CT {
|
||||
log("L1CTL_PARAM_REQ: ", dec_L1ctlUlMessage(c_ul_param_req));
|
||||
log("L1CTL_DATA_REQ: ", dec_L1ctlUlMessage(c_ul_data_req));
|
||||
log("L1CTL_CCCH_MODE_REQ: ", dec_L1ctlUlMessage(c_ul_ccch_mode_req));
|
||||
log("L1CTL_RESET_REQ: ", dec_L1ctlUlMessage(c_ul_reset_req));
|
||||
log("L1CTL_DM_EST_REQ: ", dec_L1ctlUlMessage(c_ul_dm_est_req));
|
||||
log("L1CTL_RACH_REQ: ", dec_L1ctlUlMessage(c_ul_rach_req));
|
||||
log("L1CTL_DATA_IND: ", dec_L1ctlDlMessage(c_dl_data_ind));
|
||||
setverdict(pass);
|
||||
}
|
||||
|
||||
/* master function establishing a dedicated radio channel */
|
||||
/* master function establishing a dedicated radio channel (takes care of RACH/IMM.ASS handling) */
|
||||
function f_establish_dcch() runs on dummy_CT {
|
||||
var ImmediateAssignment imm_ass;
|
||||
var GsmFrameNumber rach_fn;
|
||||
var uint8_t ra := 23;
|
||||
var BCCH_tune_req tune_req := { arfcn := { false, 871 }, combined_ccch := true };
|
||||
var DCCH_establish_req est_req := { ra := 23 };
|
||||
|
||||
/* send FB/SB req to sync to cell */
|
||||
f_L1CTL_FBSB(L1CTL, { false, 871 }, CCCH_MODE_COMBINED);
|
||||
/* send RACH request and obtain FN at which it was sent */
|
||||
rach_fn := f_L1CTL_RACH(L1CTL, ra);
|
||||
/* wait for receiving matching IMM ASS */
|
||||
imm_ass := f_L1CTL_WAIT_IMM_ASS(L1CTL, ra, rach_fn)
|
||||
/* send DM_EST_REQ */
|
||||
f_L1CTL_DM_EST_REQ_IA(L1CTL, imm_ass);
|
||||
|
||||
chan_desc := imm_ass.chan_desc;
|
||||
LAPDM.send(tune_req);
|
||||
LAPDM.send(est_req);
|
||||
LAPDM.receive(DCCH_establish_res:?);
|
||||
}
|
||||
|
||||
/* send some data over an established dedicated radio channel */
|
||||
function f_send_l2(template RslLinkId link_id, octetstring l2_data) runs on dummy_CT {
|
||||
L1CTL.send(t_L1CTL_DATA_REQ(chan_desc.chan_nr, link_id, l2_data));
|
||||
}
|
||||
|
||||
/* send some data over an established dedicated radio channel */
|
||||
function f_send_l2_lapdm_b(template RslLinkId link_id, template LapdmFrameB b) runs on dummy_CT {
|
||||
var octetstring l2_data := enc_LapdmFrameB(valueof(b));
|
||||
L1CTL.send(t_L1CTL_DATA_REQ(chan_desc.chan_nr, link_id, l2_data));
|
||||
}
|
||||
|
||||
|
||||
function f_recv_l2() runs on dummy_CT return octetstring {
|
||||
var L1ctlDlMessage dl;
|
||||
var octetstring l2_data;
|
||||
timer T := 5.0;
|
||||
T.start
|
||||
alt {
|
||||
[] L1CTL.receive(t_L1CTL_DATA_IND(chan_desc.chan_nr)) -> value dl { l2_data := dl.payload.data_ind.payload };
|
||||
[] L1CTL.receive { repeat; };
|
||||
[] T.timeout { setverdict(fail, "Timeout waiting for DL data"); };
|
||||
}
|
||||
return l2_data;
|
||||
}
|
||||
|
||||
/* release the dedicated radio channel */
|
||||
/* helper function releasing dedicated radio channel physically (no Um signaling!) */
|
||||
function f_release_dcch() runs on dummy_CT {
|
||||
L1CTL.send(t_L1CTL_DM_REL_REQ(chan_desc.chan_nr));
|
||||
var DCCH_release_req rel_req := {};
|
||||
LAPDM.send(rel_req);
|
||||
}
|
||||
|
||||
template LapdmFrameB LAPDm_SABM(template GsmSapi sapi, template octetstring payload) := {
|
||||
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, template octetstring payload) := {
|
||||
b := {
|
||||
addr := tr_LapdmAddr(sapi, false),
|
||||
ctrl := t_LapdmCtrlSABM(true),
|
||||
len := t_LapdmLengthIndicator(lengthof(payload)),
|
||||
len := lengthof(payload),
|
||||
m := false,
|
||||
el := 1,
|
||||
payload := payload
|
||||
}
|
||||
}
|
||||
|
||||
testcase TC_l1ctl() runs on dummy_CT {
|
||||
f_init();
|
||||
/* template for a valid UA frame */
|
||||
template LapdmFrame LAPDm_B_UA(template GsmSapi sapi, template 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, template 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();
|
||||
|
||||
f_send_l2_lapdm_b(ts_RslLinkID_DCCH(0), LAPDm_SABM(0, 'FEFE'O));
|
||||
f_recv_l2();
|
||||
|
||||
//f_send_l2(ts_RslLinkID_DCCH(0), '000102030405060708090a0b0c0d0e0f10111213141516'O);
|
||||
|
||||
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(sapi, use_sacch, LAPDm_B_UA(sapi, payload))) { result := true; }
|
||||
[] LAPDM.receive(t_PH_DATA(sapi, 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 { setverdict(fail); }
|
||||
}
|
||||
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 (not f_test_sabm_results_in_ua(0, false, ''O)) {
|
||||
setverdict(fail);
|
||||
}
|
||||
setverdict(pass);
|
||||
}
|
||||
|
||||
testcase TC_sabm_ua_dcch_sapi3() runs on dummy_CT {
|
||||
f_init();
|
||||
if (not f_test_sabm_results_in_ua(3, false, 'FEFE'O)) {
|
||||
setverdict(fail);
|
||||
}
|
||||
setverdict(pass);
|
||||
}
|
||||
|
||||
testcase TC_sabm_ua_dcch_sapi4() runs on dummy_CT {
|
||||
f_init();
|
||||
if (not f_test_sabm_results_in_ua(4, false, 'FEFE'O)) {
|
||||
setverdict(fail);
|
||||
}
|
||||
setverdict(pass);
|
||||
}
|
||||
|
||||
|
||||
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_selftest());
|
||||
execute(TC_l1ctl());
|
||||
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());
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) */
|
||||
}
|
||||
}
|
|
@ -116,7 +116,7 @@ module LAPDm_Types {
|
|||
};
|
||||
|
||||
template LapdmCtrl t_LapdmCtrlUA(template boolean f) modifies t_LapdmCtrlU := {
|
||||
u := { u2 := '01'B, p_f := f, u := '011'B }
|
||||
u := { u2 := '00'B, p_f := f, u := '011'B }
|
||||
};
|
||||
|
||||
external function dec_LapdmAddressField(in octetstring stream) return LapdmAddressField
|
||||
|
@ -154,16 +154,18 @@ module LAPDm_Types {
|
|||
type record LapdmFrameB {
|
||||
LapdmAddressField addr,
|
||||
LapdmCtrl ctrl,
|
||||
LapdmLengthIndicator len,
|
||||
uint6_t len,
|
||||
boolean m,
|
||||
uint1_t el (1),
|
||||
octetstring payload
|
||||
} with { variant "" };
|
||||
} 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,
|
||||
|
|
Loading…
Reference in New Issue