fixeria submitted this change.

View Change

Approvals: Jenkins Builder: Verified pespin: Looks good to me, but someone else must approve laforge: Looks good to me, approved
trxcon: allow populating global SACCH cache via L1CTL

There is a time window between activation of a dedicated channel and
receipt of a L1CTL_DATA_REQ with the first RR Measurement Report, in
which trxcon may need to start transmission on Uplink SACCH.

In this case trxcon is using a dummy SACCH block with hard-coded L1
SACCH header values and hard-coded Measurement Results. This mimics
behavior of the layer1 implementation in firmware for Calypso phones.

When running the mobile application, this error can be seen:

DAPP ERROR trxcon(0)[0x55ee57bee1a0]{FBSB_SEARCH}:
Event TRXCON_EV_RX_DATA_IND not permitted

which means that the mobile is sending L1CTL_DATA_REQ *before*
establishing a dedicated channel. And this message contains an
RR Measurement Report. The idea behind this is to populate the
SACCH cache in advance and thus avoid sending dummy values.

Let's allow the L2 apps populating SACCH cache before establishing
a dedicated connection using new TRXCON_EV_UPDATE_SACCH_CACHE_REQ.

Change-Id: I0f467fc07cf844cc73465f235b36ba7d00788c9f
Related: OS#5635, OS#5599
---
M src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
M src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
M src/host/trxcon/src/l1ctl.c
M src/host/trxcon/src/sched_prim.c
M src/host/trxcon/src/sched_trx.c
M src/host/trxcon/src/trxcon_fsm.c
6 files changed, 75 insertions(+), 63 deletions(-)

diff --git a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
index 3f7dae0..04303f0 100644
--- a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
+++ b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
@@ -374,6 +374,8 @@
void (*clock_cb)(struct l1sched_state *sched);
/*! List of timeslots maintained by this scheduler */
struct l1sched_ts *ts[TRX_TS_COUNT];
+ /*! SACCH cache (common for all lchans) */
+ uint8_t sacch_cache[GSM_MACBLOCK_LEN];
/*! BSIC value learned from SCH bursts */
uint8_t bsic;
/*! Logging context (used as prefix for messages) */
diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
index eed3d61..2a6f7d5 100644
--- a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
+++ b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
@@ -25,6 +25,7 @@
TRXCON_EV_SET_TCH_MODE_REQ,
TRXCON_EV_SET_PHY_CONFIG_REQ,
TRXCON_EV_TX_ACCESS_BURST_REQ,
+ TRXCON_EV_UPDATE_SACCH_CACHE_REQ,
TRXCON_EV_DEDICATED_ESTABLISH_REQ,
TRXCON_EV_DEDICATED_RELEASE_REQ,
TRXCON_EV_TX_TRAFFIC_REQ,
diff --git a/src/host/trxcon/src/l1ctl.c b/src/host/trxcon/src/l1ctl.c
index 28086a2..4d6bed2 100644
--- a/src/host/trxcon/src/l1ctl.c
+++ b/src/host/trxcon/src/l1ctl.c
@@ -644,10 +644,18 @@
"Recv %s Req (chan_nr=0x%02x, link_id=0x%02x, len=%zu)\n",
traffic ? "TRAFFIC" : "DATA", req.chan_nr, req.link_id, req.data_len);

- if (traffic)
- osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_TX_TRAFFIC_REQ, &req);
- else
- osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_TX_DATA_REQ, &req);
+ switch (trxcon->fi->state) {
+ case TRXCON_ST_DEDICATED:
+ if (traffic)
+ osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_TX_TRAFFIC_REQ, &req);
+ else
+ osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_TX_DATA_REQ, &req);
+ break;
+ default:
+ if (!traffic && req.link_id == 0x40) /* only for SACCH */
+ osmo_fsm_inst_dispatch(trxcon->fi, TRXCON_EV_UPDATE_SACCH_CACHE_REQ, &req);
+ /* TODO: log an error about uhnandled DATA.req / TRAFFIC.req */
+ }

msgb_free(msg);
return 0;
diff --git a/src/host/trxcon/src/sched_prim.c b/src/host/trxcon/src/sched_prim.c
index 9b6d28d..f97e505 100644
--- a/src/host/trxcon/src/sched_prim.c
+++ b/src/host/trxcon/src/sched_prim.c
@@ -116,8 +116,7 @@
}

/**
- * Composes a new primitive using either cached (if populated),
- * or "dummy" Measurement Report message.
+ * Composes a new primitive from cached RR Measurement Report.
*
* @param lchan lchan to assign a primitive
* @return SACCH primitive to be transmitted
@@ -125,38 +124,8 @@
static struct l1sched_ts_prim *prim_compose_mr(struct l1sched_lchan_state *lchan)
{
struct l1sched_ts_prim *prim;
- uint8_t *mr_src_ptr;
bool cached;

- /* "Dummy" Measurement Report */
- static const uint8_t meas_rep_dummy[] = {
- /* L1 SACCH pseudo-header */
- 0x0f, 0x00,
-
- /* LAPDm header */
- 0x01, 0x03, 0x49,
-
- /* RR Management messages, Measurement Report */
- 0x06, 0x15,
-
- /* Measurement results (see 3GPP TS 44.018, section 10.5.2.20):
- * 0... .... = BA-USED: 0
- * .0.. .... = DTX-USED: DTX was not used
- * ..11 0110 = RXLEV-FULL-SERVING-CELL: -57 <= x < -56 dBm (54)
- * 0... .... = 3G-BA-USED: 0
- * .1.. .... = MEAS-VALID: The measurement results are not valid
- * ..11 0110 = RXLEV-SUB-SERVING-CELL: -57 <= x < -56 dBm (54)
- * 0... .... = SI23_BA_USED: 0
- * .000 .... = RXQUAL-FULL-SERVING-CELL: BER < 0.2%, Mean value 0.14% (0)
- * .... 000. = RXQUAL-SUB-SERVING-CELL: BER < 0.2%, Mean value 0.14% (0)
- * .... ...1 11.. .... = NO-NCELL-M: Neighbour cell information not available */
- 0x36, 0x76, 0x01, 0xc0,
-
- /* 0** -- Padding with zeroes */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
-
/* Allocate a new primitive */
prim = prim_alloc(lchan, GSM_MACBLOCK_LEN, L1SCHED_PRIM_DATA,
l1sched_lchan_desc[lchan->type].chan_nr,
@@ -167,43 +136,24 @@
cached = (lchan->sacch.mr_cache[2] != 0x00
&& lchan->sacch.mr_cache[3] != 0x00
&& lchan->sacch.mr_cache[4] != 0x00);
- if (cached) { /* Use the cached one */
- mr_src_ptr = lchan->sacch.mr_cache;
- lchan->sacch.mr_cache_usage++;
- } else { /* Use "dummy" one */
- mr_src_ptr = (uint8_t *) meas_rep_dummy;
+ if (!cached) {
+ memcpy(&lchan->sacch.mr_cache[0],
+ &lchan->ts->sched->sacch_cache[0],
+ sizeof(lchan->sacch.mr_cache));
}

/* Compose a new Measurement Report primitive */
- memcpy(prim->payload, mr_src_ptr, GSM_MACBLOCK_LEN);
-
- /**
- * Update the L1 SACCH pseudo-header (only for cached MRs)
- *
- * TODO: filling of the actual values into cached Measurement
- * Reports would break the distance spoofing feature. If it
- * were known whether the spoofing is enabled or not, we could
- * decide whether to update the cached L1 SACCH header here.
- */
- if (!cached) {
-#warning "FIXME: no direct access to trxcon->l1p.{tx_power,ta}"
-#if 0
- prim->payload[0] = lchan->ts->sched->trx->tx_power;
- prim->payload[1] = lchan->ts->sched->trx->ta;
-#endif
- }
+ memcpy(&prim->payload[0], &lchan->sacch.mr_cache[0], GSM_MACBLOCK_LEN);

/* Inform about the cache usage count */
- if (cached && lchan->sacch.mr_cache_usage > 5) {
+ if (++lchan->sacch.mr_cache_usage > 5) {
LOGP_LCHAND(lchan, LOGL_NOTICE,
"SACCH MR cache usage count=%u > 5 "
"=> ancient measurements, please fix!\n",
lchan->sacch.mr_cache_usage);
}

- LOGP_LCHAND(lchan, LOGL_NOTICE,
- "Using a %s Measurement Report\n",
- cached ? "cached" : "dummy");
+ LOGP_LCHAND(lchan, LOGL_NOTICE, "Using cached Measurement Report\n");

return prim;
}
diff --git a/src/host/trxcon/src/sched_trx.c b/src/host/trxcon/src/sched_trx.c
index af2d9b3..be1f820 100644
--- a/src/host/trxcon/src/sched_trx.c
+++ b/src/host/trxcon/src/sched_trx.c
@@ -39,6 +39,35 @@
int l1sched_log_cat_common = DLGLOBAL;
int l1sched_log_cat_data = DLGLOBAL;

+/* "Dummy" Measurement Report */
+static const uint8_t meas_rep_dummy[] = {
+ /* L1 SACCH pseudo-header */
+ 0x0f, 0x00,
+
+ /* LAPDm header */
+ 0x01, 0x03, 0x49,
+
+ /* RR Management messages, Measurement Report */
+ 0x06, 0x15,
+
+ /* Measurement results (see 3GPP TS 44.018, section 10.5.2.20):
+ * 0... .... = BA-USED: 0
+ * .0.. .... = DTX-USED: DTX was not used
+ * ..11 0110 = RXLEV-FULL-SERVING-CELL: -57 <= x < -56 dBm (54)
+ * 0... .... = 3G-BA-USED: 0
+ * .1.. .... = MEAS-VALID: The measurement results are not valid
+ * ..11 0110 = RXLEV-SUB-SERVING-CELL: -57 <= x < -56 dBm (54)
+ * 0... .... = SI23_BA_USED: 0
+ * .000 .... = RXQUAL-FULL-SERVING-CELL: BER < 0.2%, Mean value 0.14% (0)
+ * .... 000. = RXQUAL-SUB-SERVING-CELL: BER < 0.2%, Mean value 0.14% (0)
+ * .... ...1 11.. .... = NO-NCELL-M: Neighbour cell information not available */
+ 0x36, 0x76, 0x01, 0xc0,
+
+ /* 0** -- Padding with zeroes */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
static int l1sched_cfg_pchan_comb_req(struct l1sched_state *sched,
uint8_t tn, enum gsm_phys_chan_config pchan)
{
@@ -175,6 +204,8 @@
.priv = priv,
};

+ memcpy(&sched->sacch_cache[0], &meas_rep_dummy[0], sizeof(meas_rep_dummy));
+
if (cfg->log_prefix == NULL)
sched->log_prefix = talloc_asprintf(sched, "l1sched[0x%p]: ", sched);
else
@@ -217,6 +248,8 @@
/* Stop and reset clock counter if required */
if (reset_clock)
l1sched_clck_reset(sched);
+
+ memcpy(&sched->sacch_cache[0], &meas_rep_dummy[0], sizeof(meas_rep_dummy));
}

struct l1sched_ts *l1sched_add_ts(struct l1sched_state *sched, int tn)
diff --git a/src/host/trxcon/src/trxcon_fsm.c b/src/host/trxcon/src/trxcon_fsm.c
index 3c30565..40d5253 100644
--- a/src/host/trxcon/src/trxcon_fsm.c
+++ b/src/host/trxcon/src/trxcon_fsm.c
@@ -71,6 +71,22 @@
trxcon->l1p.ta = req->timing_advance;
break;
}
+ case TRXCON_EV_UPDATE_SACCH_CACHE_REQ:
+ {
+ const struct trxcon_param_tx_traffic_data_req *req = data;
+
+ if (req->link_id != L1SCHED_CH_LID_SACCH) {
+ LOGPFSML(fi, LOGL_ERROR, "Unexpected link_id=0x%02x\n", req->link_id);
+ break;
+ }
+ if (req->data_len != GSM_MACBLOCK_LEN) {
+ LOGPFSML(fi, LOGL_ERROR, "Unexpected data length=%u\n", req->data_len);
+ break;
+ }
+
+ memcpy(&trxcon->sched->sacch_cache[0], req->data, req->data_len);
+ break;
+ }
default:
OSMO_ASSERT(0);
}
@@ -451,6 +467,7 @@
OSMO_VALUE_STRING(TRXCON_EV_SET_TCH_MODE_REQ),
OSMO_VALUE_STRING(TRXCON_EV_SET_PHY_CONFIG_REQ),
OSMO_VALUE_STRING(TRXCON_EV_TX_ACCESS_BURST_REQ),
+ OSMO_VALUE_STRING(TRXCON_EV_UPDATE_SACCH_CACHE_REQ),
OSMO_VALUE_STRING(TRXCON_EV_DEDICATED_ESTABLISH_REQ),
OSMO_VALUE_STRING(TRXCON_EV_DEDICATED_RELEASE_REQ),
OSMO_VALUE_STRING(TRXCON_EV_TX_TRAFFIC_REQ),
@@ -471,7 +488,8 @@
| S(TRXCON_EV_L2IF_FAILURE)
| S(TRXCON_EV_RESET_FULL_REQ)
| S(TRXCON_EV_RESET_SCHED_REQ)
- | S(TRXCON_EV_SET_PHY_CONFIG_REQ),
+ | S(TRXCON_EV_SET_PHY_CONFIG_REQ)
+ | S(TRXCON_EV_UPDATE_SACCH_CACHE_REQ),
.allstate_action = &trxcon_allstate_action,
.timer_cb = &trxcon_timer_cb,
};

3 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one.

To view, visit change 28874. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: I0f467fc07cf844cc73465f235b36ba7d00788c9f
Gerrit-Change-Number: 28874
Gerrit-PatchSet: 4
Gerrit-Owner: fixeria <vyanitskiy@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de>
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>
Gerrit-MessageType: merged