aboutsummaryrefslogtreecommitdiffstats
path: root/library/RSL_Emulation.ttcn
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2018-10-24 20:36:16 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2018-11-06 16:22:57 +0000
commit6451b04aedc95e1cc867c4096037a7f86ccf80bc (patch)
treeda4529c9c1ae40c13262432f27e0f9e8abcb5706 /library/RSL_Emulation.ttcn
parentd686a8a54873eb61fae7d55cb001378dae3fbd7d (diff)
bts: f_est_dchan: verify Chan Rqd originated by RACH arrives on RSL
We cannot notify RSL Emulation layer about expecting a specific FN (during ts_RSLDC_ChanRqd) because we only know the FN after sending the RACH request, and since notification to RSL Emulation happens async, it can happen (verified) that ChanRqd message from BTS arrives and is handled before we register the RACH req into the ConnectionTable. Change-Id: I438fd3ee82d88498d928dbcc89ce9bd80d37ab64
Diffstat (limited to 'library/RSL_Emulation.ttcn')
-rw-r--r--library/RSL_Emulation.ttcn50
1 files changed, 46 insertions, 4 deletions
diff --git a/library/RSL_Emulation.ttcn b/library/RSL_Emulation.ttcn
index cf02d00c..cdeca746 100644
--- a/library/RSL_Emulation.ttcn
+++ b/library/RSL_Emulation.ttcn
@@ -47,14 +47,19 @@ type component RSL_DchanHdlr {
type record RSLDC_ChanRqd {
OCT1 ra,
- GsmFrameNumber fn
+ GsmFrameNumber fn optional
};
-template RSLDC_ChanRqd ts_RSLDC_ChanRqd(OCT1 ra, GsmFrameNumber fn) := {
+template (value) RSLDC_ChanRqd ts_RSLDC_ChanRqd(OCT1 ra, GsmFrameNumber fn) := {
ra := ra,
fn := fn
}
+template (value) RSLDC_ChanRqd ts_RSLDC_ChanRqd_anyFN(OCT1 ra) := {
+ ra := ra,
+ fn := omit
+}
+
type port RSL_DCHAN_PT message {
inout RSLDC_ChanRqd, RSL_Message;
} with { extension "internal" };
@@ -183,15 +188,36 @@ runs on RSL_Emulation_CT return integer {
return -1;
}
+/* Matches by only RA if FN is ommited in one of the connections allocated */
+private function f_cid_by_ra_fn2(OCT1 ra, RSL_IE_FrameNumber fn)
+runs on RSL_Emulation_CT return integer {
+ var integer i;
+ for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
+ if (ispresent(ConnectionTable[i].ra) and
+ ConnectionTable[i].ra == ra) {
+ if (not ispresent(ConnectionTable[i].ra_fn) or
+ fn == valueof(ts_RSL_IE_FrameNumber(ConnectionTable[i].ra_fn))) {
+ return i;
+ }
+ }
+ }
+ log("No Dchan handler for ", ra, fn);
+ return -1;
+}
+
/* create an ew client with given RA and FN */
-private function f_cid_create(OCT1 ra, GsmFrameNumber fn, RSL_DchanHdlr comp_ref)
+private function f_cid_create(OCT1 ra, template (omit) GsmFrameNumber fn, RSL_DchanHdlr comp_ref)
runs on RSL_Emulation_CT {
var integer i;
for (i := 0; i < sizeof(ConnectionTable); i := i+1) {
if (not ispresent(ConnectionTable[i].ra) and
not ispresent(ConnectionTable[i].trx_nr)) {
ConnectionTable[i].ra := ra;
- ConnectionTable[i].ra_fn := fn;
+ if (ispresent(fn)) {
+ ConnectionTable[i].ra_fn := valueof(fn);
+ } else {
+ ConnectionTable[i].ra_fn := omit;
+ }
ConnectionTable[i].comp_ref := comp_ref;
return;
}
@@ -394,6 +420,17 @@ function main(boolean bts_role := true) runs on RSL_Emulation_CT {
}
}
}
+ [not bts_role] IPA_PT.receive(tr_RSL(tr_RSL_CHAN_RQD(?))) -> value rx_rsl {
+ var RSL_IE_RequestRef req_ref;
+ req_ref := rx_rsl.rsl.ies[1].body.req_ref;
+ cid := f_cid_by_ra_fn2(req_ref.ra, req_ref.frame_nr);
+ if (cid != -1) {
+ CLIENT_PT.send(rx_rsl.rsl) to ConnectionTable[cid].comp_ref;
+ f_cid_clear(cid);
+ } else {
+ CCHAN_PT.send(rx_rsl);
+ }
+ }
[bts_role] IPA_PT.receive(tr_RSL(tr_RSL_PAGING_CMD(?, ?))) -> value rx_rsl {
/* broadcast to all clients? */
@@ -446,6 +483,11 @@ function main(boolean bts_role := true) runs on RSL_Emulation_CT {
ts_RSL_CHAN_RQD(chan_rqd.ra, chan_rqd.fn)));
}
+ [not bts_role] CLIENT_PT.receive(RSLDC_ChanRqd:?) -> value chan_rqd sender vc_conn {
+ /* Store the knowledge that this sender has requested a certain RQ+time */
+ f_cid_create(chan_rqd.ra, chan_rqd.fn, vc_conn);
+ }
+
[] CLIENT_PT.receive(tr_RSL_MsgType(?)) -> value rx_rsl_msg sender vc_conn {
/* forward to BSC */
cid := f_cid_by_comp_ref(vc_conn);