LAPDm_RAW_PT: Add support for TBF mode (GPRS)
This commit is contained in:
parent
1dcc371539
commit
4b6c772b15
|
@ -8,6 +8,7 @@ module LAPDm_RAW_PT {
|
|||
import from L1CTL_Types all;
|
||||
import from L1CTL_PortType all;
|
||||
import from LAPDm_Types all;
|
||||
import from RLCMAC_Types all;
|
||||
|
||||
/* request to tune to a given ARFCN and start BCCH decoding */
|
||||
type record BCCH_tune_req {
|
||||
|
@ -25,6 +26,10 @@ module LAPDm_RAW_PT {
|
|||
charstring err optional
|
||||
}
|
||||
|
||||
type record TBF_establish_res {
|
||||
charstring err optional
|
||||
}
|
||||
|
||||
type record DCCH_release_req {
|
||||
}
|
||||
|
||||
|
@ -35,23 +40,46 @@ module LAPDm_RAW_PT {
|
|||
LapdmFrame lapdm
|
||||
}
|
||||
|
||||
type record TBF_establish_req {
|
||||
uint8_t ra
|
||||
}
|
||||
|
||||
/* PH-DATA.ind / PH-DATA.req */
|
||||
type record RLCMAC_ph_data_ind {
|
||||
GprsCodingScheme cs,
|
||||
RlcmacDlBlock block
|
||||
}
|
||||
type record RLCMAC_ph_data_req {
|
||||
uint8_t tbf_id,
|
||||
GprsCodingScheme cs,
|
||||
RlcmacUlBlock block
|
||||
}
|
||||
|
||||
/* port from our (internal) point of view */
|
||||
type port LAPDm_SP_PT message {
|
||||
in BCCH_tune_req,
|
||||
DCCH_establish_req,
|
||||
DCCH_release_req,
|
||||
TBF_establish_req,
|
||||
RLCMAC_ph_data_req,
|
||||
LAPDm_ph_data;
|
||||
out DCCH_establish_res,
|
||||
TBF_establish_res,
|
||||
RLCMAC_ph_data_ind,
|
||||
LAPDm_ph_data;
|
||||
} with {extension "internal"};
|
||||
|
||||
/* port from user (external) point of view */
|
||||
type port LAPDm_PT message {
|
||||
in DCCH_establish_res,
|
||||
TBF_establish_res,
|
||||
RLCMAC_ph_data_ind,
|
||||
LAPDm_ph_data;
|
||||
out BCCH_tune_req,
|
||||
DCCH_establish_req,
|
||||
DCCH_release_req,
|
||||
TBF_establish_req,
|
||||
RLCMAC_ph_data_req,
|
||||
LAPDm_ph_data;
|
||||
} with {extension "internal"};
|
||||
|
||||
|
@ -66,7 +94,8 @@ module LAPDm_RAW_PT {
|
|||
PH_STATE_BCH,
|
||||
PH_STATE_SEARCHING_BCH,
|
||||
PH_STATE_TUNING_DCH,
|
||||
PH_STATE_DCH
|
||||
PH_STATE_DCH,
|
||||
PH_STATE_TBF
|
||||
}
|
||||
|
||||
type component lapdm_CT {
|
||||
|
@ -98,7 +127,7 @@ module LAPDm_RAW_PT {
|
|||
/* 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);
|
||||
set_ph_state(PH_STATE_BCH);
|
||||
}
|
||||
|
||||
/* tune to given ARFCN and start BCCH/CCCH decoding */
|
||||
|
@ -111,6 +140,8 @@ module LAPDm_RAW_PT {
|
|||
if (ph_state == PH_STATE_DCH) {
|
||||
/* release any previous DCH */
|
||||
f_release_dcch();
|
||||
} else if (ph_state == PH_STATE_TBF) {
|
||||
f_release_tbf();
|
||||
}
|
||||
|
||||
set_ph_state(PH_STATE_SEARCHING_BCH);
|
||||
|
@ -142,12 +173,102 @@ module LAPDm_RAW_PT {
|
|||
set_ph_state(PH_STATE_DCH);
|
||||
}
|
||||
|
||||
/* initialize a tfi_usf array with "not used" value 255 for all TN */
|
||||
function f_TfiUsfArrInit() return TfiUsfArr {
|
||||
var TfiUsfArr tua := { 255, 255, 255, 255, 255, 255, 255, 255 };
|
||||
return tua;
|
||||
}
|
||||
|
||||
/* set TFI/USF value for one given timeslot number (index) */
|
||||
function f_TfiUsfArrSet(inout TfiUsfArr a, in uint8_t idx, in uint8_t tfi_usf) {
|
||||
a[idx] := tfi_usf;
|
||||
}
|
||||
|
||||
/* Match an IMM.ASS for an Uplink TBF with a dynamic allocation */
|
||||
template ImmediateAssignment t_IMM_ASS_TBF_UL_DYN(uint8_t ra, GsmFrameNumber fn) modifies t_IMM_ASS := {
|
||||
ded_or_tbf := { spare := ?, tma := ?, downlink := false, tbf := true},
|
||||
chan_desc := omit,
|
||||
pkt_chan_desc := ?,
|
||||
rest_octets := {
|
||||
presence := '11'B,
|
||||
ll := omit,
|
||||
lh := omit,
|
||||
hl := omit,
|
||||
hh := {
|
||||
presence := '00'B,
|
||||
ul := {
|
||||
presence := '1'B,
|
||||
dynamic := {
|
||||
tfi_assignment := ?,
|
||||
polling := ?,
|
||||
spare := '0'B,
|
||||
usf := ?,
|
||||
usf_granularity := ?,
|
||||
p0_present := ?,
|
||||
p0 := *,
|
||||
pr_mode := *,
|
||||
ch_coding_cmd := ?,
|
||||
tlli_block_chan_coding:= ?,
|
||||
alpha_present := ?,
|
||||
alpha := *,
|
||||
gamma := ?,
|
||||
ta_index_present := ?,
|
||||
ta_index := *,
|
||||
tbf_starting_time_present := ?,
|
||||
tbf_starting_time := *
|
||||
},
|
||||
single := omit
|
||||
},
|
||||
dl := omit
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private function f_establish_tbf(uint8_t ra) runs on lapdm_CT {
|
||||
var ImmediateAssignment imm_ass;
|
||||
var GsmFrameNumber rach_fn;
|
||||
var TfiUsfArr tua := f_TfiUsfArrInit();
|
||||
|
||||
/* 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);
|
||||
|
||||
if (match(imm_ass, t_IMM_ASS_TBF_UL_DYN(ra, rach_fn))) {
|
||||
set_ph_state(PH_STATE_TBF);
|
||||
|
||||
/* store/save channel description */
|
||||
//chan_desc := imm_ass.chan_desc;
|
||||
|
||||
/* Important: ARFCN, TN, TSC, USF, USF_GRANULARITY, CH_CODING_CMD */
|
||||
f_TfiUsfArrSet(tua, imm_ass.pkt_chan_desc.tn, imm_ass.rest_octets.hh.ul.dynamic.usf);
|
||||
f_L1CTL_TBF_CFG(L1CTL, true, tua);
|
||||
} else {
|
||||
/* FIXME: single block uplink allocation */
|
||||
log("Failed to match ", t_IMM_ASS_TBF_UL_DYN(ra, rach_fn));
|
||||
log("Non-dynamic UL TBF assignment not supported yet");
|
||||
}
|
||||
}
|
||||
|
||||
private function f_release_tbf() runs on lapdm_CT {
|
||||
var TfiUsfArr tua := f_TfiUsfArrInit();
|
||||
/* send "all timeslots unused" for both UL and DL */
|
||||
f_L1CTL_TBF_CFG(L1CTL, true, tua);
|
||||
f_L1CTL_TBF_CFG(L1CTL, false, tua);
|
||||
/* L1 will then fall back to BCCH/CCCH */
|
||||
set_ph_state(PH_STATE_BCH);
|
||||
}
|
||||
|
||||
function ScanEvents() runs on lapdm_CT {
|
||||
var L1ctlDlMessage dl;
|
||||
var BCCH_tune_req bt;
|
||||
var LAPDm_ph_data lpd;
|
||||
var RLCMAC_ph_data_ind rpdi;
|
||||
var RLCMAC_ph_data_req rpdr;
|
||||
var DCCH_establish_req est_req;
|
||||
var DCCH_establish_res est_res;
|
||||
var TBF_establish_req tbf_req;
|
||||
|
||||
while (true) {
|
||||
if (ph_state == PH_STATE_NULL) {
|
||||
|
@ -194,6 +315,18 @@ module LAPDm_RAW_PT {
|
|||
LAPDM_SP.send(res);
|
||||
}
|
||||
|
||||
/* Establish TBF / packet transfer mode */
|
||||
[] LAPDM_SP.receive(TBF_establish_req:?) -> value tbf_req {
|
||||
var TBF_establish_res res;
|
||||
f_establish_tbf(tbf_req.ra);
|
||||
if (ph_state == PH_STATE_TBF) {
|
||||
res := { err := omit };
|
||||
} else {
|
||||
res := { err := "Unable to establish TBF" };
|
||||
}
|
||||
LAPDM_SP.send(res);
|
||||
}
|
||||
|
||||
[] LAPDM_SP.receive {}
|
||||
[] L1CTL.receive {}
|
||||
|
||||
|
@ -238,8 +371,37 @@ module LAPDm_RAW_PT {
|
|||
[] L1CTL.receive {}
|
||||
|
||||
|
||||
}
|
||||
} else if (ph_state == PH_STATE_TBF) {
|
||||
alt {
|
||||
|
||||
/* decode + forward any blocks from L1 to L23*/
|
||||
[] L1CTL.receive(t_L1CTL_DATA_IND(t_RslChanNr_PDCH(?))) -> value dl {
|
||||
rpdi.block := dec_RlcmacDlBlock(dl.payload.data_ind.payload);
|
||||
rpdi.cs := CS1; /* FIXME */
|
||||
log("RPDI: ", rpdi);
|
||||
LAPDM_SP.send(rpdi);
|
||||
}
|
||||
|
||||
[] L1CTL.receive { }
|
||||
|
||||
/* encode + forward any blocks from L23 to L1 */
|
||||
[] LAPDM_SP.receive(RLCMAC_ph_data_req:?) -> value rpdr {
|
||||
var octetstring buf;
|
||||
|
||||
buf := enc_RlcmacUlBlock(rpdr.block);
|
||||
L1CTL.send(t_L1CTL_DATA_TBF_REQ(buf, L1CTL_CS1, rpdr.tbf_id));
|
||||
}
|
||||
|
||||
/* FIXME: release TBF mode */
|
||||
[] LAPDM_SP.receive(DCCH_release_req:?) {
|
||||
/* go back to BCCH */
|
||||
f_release_tbf();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} /* while (1) */
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue