fixeria has submitted this change. (
https://gerrit.osmocom.org/c/osmocom-bb/+/28552 )
Change subject: trxcon: use abstract API for RACH primitives
......................................................................
trxcon: use abstract API for RACH primitives
Using L1CTL specific structures as the primitive payload was a
beautiful hack in the early days of trxcon. But since we're
going to separate the scheduler into an interface independent
library, we have to introduce and use an abstract API.
Change-Id: I84597d44ea7d74b8840a919ecb09988ba1980a73
Related: OS#5599, OS#3761
---
M src/host/trxcon/include/osmocom/bb/trxcon/l1sched.h
M src/host/trxcon/src/l1ctl.c
M src/host/trxcon/src/sched_lchan_rach.c
M src/host/trxcon/src/sched_prim.c
4 files changed, 78 insertions(+), 49 deletions(-)
Approvals:
Jenkins Builder: Verified
laforge: Looks good to me, but someone else must approve
pespin: Looks good to me, approved
diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/l1sched.h
b/src/host/trxcon/include/osmocom/bb/trxcon/l1sched.h
index fa7296a..03dfec3 100644
--- a/src/host/trxcon/include/osmocom/bb/trxcon/l1sched.h
+++ b/src/host/trxcon/include/osmocom/bb/trxcon/l1sched.h
@@ -55,6 +55,12 @@
L1SCHED_BURST_8PSK,
};
+enum l1sched_ts_prim_type {
+ L1SCHED_PRIM_DATA,
+ L1SCHED_PRIM_RACH8,
+ L1SCHED_PRIM_RACH11,
+};
+
/**
* These types define the different channels on a multiframe.
* Each channel has queues and can be activated individually.
@@ -299,6 +305,8 @@
struct l1sched_ts_prim {
/*! Link to queue of TS */
struct llist_head list;
+ /*! Type of primitive */
+ enum l1sched_ts_prim_type type;
/*! Logical channel type */
enum l1sched_lchan_type chan;
/*! Payload length */
@@ -307,6 +315,16 @@
uint8_t payload[0];
};
+/*! Represents a RACH (8-bit or 11-bit) primitive */
+struct l1sched_ts_prim_rach {
+ /*! RA value */
+ uint16_t ra;
+ /*! Training Sequence (only for 11-bit RA) */
+ uint8_t synch_seq;
+ /*! Transmission offset (how many frames to skip) */
+ uint8_t offset;
+};
+
/*! One scheduler instance */
struct l1sched_state {
/*! Clock state */
@@ -359,6 +377,7 @@
/* Primitive management functions */
struct l1sched_ts_prim *l1sched_prim_push(struct trx_instance *trx,
+ enum l1sched_ts_prim_type type,
uint8_t chan_nr, uint8_t link_id,
const uint8_t *pl, size_t pl_len);
@@ -379,12 +398,11 @@
#define L1SCHED_CHAN_IS_SACCH(chan) \
(l1sched_lchan_desc[chan].link_id & L1SCHED_CH_LID_SACCH)
-/* FIXME: we need a better way to identify / distinguish primitives */
#define L1SCHED_PRIM_IS_RACH11(prim) \
- (prim->payload_len == sizeof(struct l1ctl_ext_rach_req))
+ (prim->type == L1SCHED_PRIM_RACH11)
#define L1SCHED_PRIM_IS_RACH8(prim) \
- (prim->payload_len == sizeof(struct l1ctl_rach_req))
+ (prim->type == L1SCHED_PRIM_RACH8)
#define L1SCHED_PRIM_IS_RACH(prim) \
(L1SCHED_PRIM_IS_RACH8(prim) || L1SCHED_PRIM_IS_RACH11(prim))
diff --git a/src/host/trxcon/src/l1ctl.c b/src/host/trxcon/src/l1ctl.c
index a6fae33..99b843c 100644
--- a/src/host/trxcon/src/l1ctl.c
+++ b/src/host/trxcon/src/l1ctl.c
@@ -504,32 +504,37 @@
static int l1ctl_rx_rach_req(struct l1ctl_link *l1l, struct msgb *msg, bool ext)
{
- struct l1ctl_ext_rach_req *ext_req;
- struct l1ctl_rach_req *req;
struct l1ctl_info_ul *ul;
struct l1sched_ts_prim *prim;
- size_t len;
+ struct l1sched_ts_prim_rach rach;
+ enum l1sched_ts_prim_type prim_type;
int rc;
ul = (struct l1ctl_info_ul *) msg->l1h;
/* Is it extended (11-bit) RACH or not? */
if (ext) {
- ext_req = (struct l1ctl_ext_rach_req *) ul->payload;
- ext_req->offset = ntohs(ext_req->offset);
- ext_req->ra11 = ntohs(ext_req->ra11);
- len = sizeof(*ext_req);
+ const struct l1ctl_ext_rach_req *req = (void *)ul->payload;
+
+ rach = (struct l1sched_ts_prim_rach) {
+ .ra = ntohs(req->ra11),
+ .synch_seq = req->synch_seq,
+ .offset = ntohs(req->offset),
+ };
LOGP(DL1C, LOGL_NOTICE, "Received extended (11-bit) RACH request "
"(offset=%u, synch_seq=%u, ra11=0x%02hx)\n",
- ext_req->offset, ext_req->synch_seq, ext_req->ra11);
+ rach.offset, rach.synch_seq, rach.ra);
} else {
- req = (struct l1ctl_rach_req *) ul->payload;
- req->offset = ntohs(req->offset);
- len = sizeof(*req);
+ const struct l1ctl_rach_req *req = (void *)ul->payload;
+
+ rach = (struct l1sched_ts_prim_rach) {
+ .ra = req->ra,
+ .offset = ntohs(req->offset),
+ };
LOGP(DL1C, LOGL_NOTICE, "Received regular (8-bit) RACH request "
- "(offset=%u, ra=0x%02x)\n", req->offset, req->ra);
+ "(offset=%u, ra=0x%02x)\n", rach.offset, rach.ra);
}
/* The controlling L1CTL side always does include the UL info header,
@@ -544,7 +549,9 @@
* Push this primitive to the transmit queue.
* Indicated timeslot needs to be configured.
*/
- prim = l1sched_prim_push(l1l->trx, ul->chan_nr, ul->link_id, ul->payload,
len);
+ prim_type = ext ? L1SCHED_PRIM_RACH11 : L1SCHED_PRIM_RACH8;
+ prim = l1sched_prim_push(l1l->trx, prim_type, ul->chan_nr, ul->link_id,
+ (const uint8_t *)&rach, sizeof(rach));
if (prim == NULL)
rc = -ENOMEM;
@@ -713,7 +720,8 @@
chan_nr, link_id, payload_len);
/* Push this primitive to transmit queue */
- prim = l1sched_prim_push(l1l->trx, chan_nr, link_id, ul->payload, payload_len);
+ prim = l1sched_prim_push(l1l->trx, L1SCHED_PRIM_DATA,
+ chan_nr, link_id, ul->payload, payload_len);
if (prim == NULL)
rc = -ENOMEM;
diff --git a/src/host/trxcon/src/sched_lchan_rach.c
b/src/host/trxcon/src/sched_lchan_rach.c
index ffec1d0..d322030 100644
--- a/src/host/trxcon/src/sched_lchan_rach.c
+++ b/src/host/trxcon/src/sched_lchan_rach.c
@@ -76,63 +76,56 @@
struct l1sched_lchan_state *lchan,
struct l1sched_burst_req *br)
{
- struct l1ctl_ext_rach_req *ext_req = NULL;
- struct l1ctl_rach_req *req = NULL;
- enum rach_synch_seq_t synch_seq;
+ struct l1sched_ts_prim_rach *rach;
uint8_t *burst_ptr = br->burst;
uint8_t payload[36];
+ uint8_t ra_buf[2];
int i, rc;
+ rach = (struct l1sched_ts_prim_rach *)lchan->prim->payload;
+
+ /* Delay sending according to offset value */
+ if (rach->offset-- > 0)
+ return 0;
+
/* Is it extended (11-bit) RACH or not? */
if (L1SCHED_PRIM_IS_RACH11(lchan->prim)) {
- ext_req = (struct l1ctl_ext_rach_req *) lchan->prim->payload;
- synch_seq = ext_req->synch_seq;
-
/* Check requested synch. sequence */
- if (synch_seq >= RACH_SYNCH_SEQ_NUM) {
- LOGP(DSCHD, LOGL_ERROR, "Unknown RACH synch. sequence=0x%02x\n",
synch_seq);
+ if (rach->synch_seq >= RACH_SYNCH_SEQ_NUM) {
+ LOGP(DSCHD, LOGL_ERROR, "Unknown RACH synch. sequence=0x%02x\n",
+ rach->synch_seq);
/* Forget this primitive */
l1sched_prim_drop(lchan);
return -ENOTSUP;
}
- /* Delay sending according to offset value */
- if (ext_req->offset-- > 0)
- return 0;
-
/* Encode extended (11-bit) payload */
- rc = gsm0503_rach_ext_encode(payload, ext_req->ra11, trx->bsic, true);
+ rc = gsm0503_rach_ext_encode(payload, rach->ra, trx->bsic, true);
if (rc) {
LOGP(DSCHD, LOGL_ERROR, "Could not encode extended RACH burst "
- "(ra=%u bsic=%u)\n", ext_req->ra11, trx->bsic);
+ "(ra=%u bsic=%u)\n", rach->ra, trx->bsic);
/* Forget this primitive */
l1sched_prim_drop(lchan);
return rc;
}
} else if (L1SCHED_PRIM_IS_RACH8(lchan->prim)) {
- req = (struct l1ctl_rach_req *) lchan->prim->payload;
- synch_seq = RACH_SYNCH_SEQ_TS0;
-
- /* Delay sending according to offset value */
- if (req->offset-- > 0)
- return 0;
+ rach->synch_seq = RACH_SYNCH_SEQ_TS0;
/* Encode regular (8-bit) payload */
- rc = gsm0503_rach_ext_encode(payload, req->ra, trx->bsic, false);
+ rc = gsm0503_rach_ext_encode(payload, rach->ra, trx->bsic, false);
if (rc) {
LOGP(DSCHD, LOGL_ERROR, "Could not encode RACH burst "
- "(ra=%u bsic=%u)\n", req->ra, trx->bsic);
+ "(ra=%u bsic=%u)\n", rach->ra, trx->bsic);
/* Forget this primitive */
l1sched_prim_drop(lchan);
return rc;
}
} else {
- LOGP(DSCHD, LOGL_ERROR, "Primitive has odd length %zu (expected %zu or %zu),
"
- "so dropping...\n", lchan->prim->payload_len,
- sizeof(*req), sizeof(*ext_req));
+ LOGP(DSCHD, LOGL_ERROR, "Primitive has unexpected "
+ "type=0x%02x\n", lchan->prim->type);
l1sched_prim_drop(lchan);
return -EINVAL;
}
@@ -144,7 +137,7 @@
/* BN8-48: chosen synch. (training) sequence */
for (i = 0; i < RACH_SYNCH_SEQ_LEN; i++)
- *(burst_ptr++) = rach_synch_seq_bits[synch_seq][i] == '1';
+ *(burst_ptr++) = rach_synch_seq_bits[rach->synch_seq][i] == '1';
/* BN49-84: encrypted bits (the payload) */
memcpy(burst_ptr, payload, RACH_PAYLOAD_LEN);
@@ -156,17 +149,23 @@
LOGP(DSCHD, LOGL_NOTICE, "Scheduled %s RACH (%s) on fn=%u, tn=%u,
lchan=%s\n",
L1SCHED_PRIM_IS_RACH11(lchan->prim) ? "extended (11-bit)" : "regular
(8-bit)",
- get_value_string(rach_synch_seq_names, synch_seq), br->fn,
+ get_value_string(rach_synch_seq_names, rach->synch_seq), br->fn,
ts->index, l1sched_lchan_desc[lchan->type].name);
/* Confirm RACH request */
l1ctl_tx_rach_conf(trx->l1l, trx->band_arfcn, br->fn);
+ if (L1SCHED_PRIM_IS_RACH11(lchan->prim)) {
+ ra_buf[0] = (uint8_t)(rach->ra >> 3);
+ ra_buf[1] = (uint8_t)(rach->ra & 0x07);
+ } else {
+ ra_buf[0] = (uint8_t)(rach->ra);
+ }
+
/* Optional GSMTAP logging */
l1sched_gsmtap_send(lchan->type, br->fn, ts->index,
- trx->band_arfcn | ARFCN_UPLINK, 0, 0,
- L1SCHED_PRIM_IS_RACH11(lchan->prim) ? (uint8_t *) &ext_req->ra11 :
&req->ra,
- L1SCHED_PRIM_IS_RACH11(lchan->prim) ? 2 : 1);
+ trx->band_arfcn | ARFCN_UPLINK, 0, 0,
+ &ra_buf[0], L1SCHED_PRIM_IS_RACH11(lchan->prim) ? 2 : 1);
/* Forget processed primitive */
l1sched_prim_drop(lchan);
diff --git a/src/host/trxcon/src/sched_prim.c b/src/host/trxcon/src/sched_prim.c
index f9b4213..55a23d1 100644
--- a/src/host/trxcon/src/sched_prim.c
+++ b/src/host/trxcon/src/sched_prim.c
@@ -40,11 +40,13 @@
*
* @param ctx parent talloc context
* @param pl_len prim payload length
+ * @param type prim payload type
* @param chan_nr RSL channel description (used to set a proper chan)
* @param link_id RSL link description (used to set a proper chan)
* @return allocated primitive or NULL
*/
static struct l1sched_ts_prim *prim_alloc(void *ctx, size_t pl_len,
+ enum l1sched_ts_prim_type type,
uint8_t chan_nr, uint8_t link_id)
{
enum l1sched_lchan_type lchan_type;
@@ -68,6 +70,7 @@
/* Init primitive header */
prim->payload_len = pl_len;
prim->chan = lchan_type;
+ prim->type = type;
return prim;
}
@@ -84,6 +87,7 @@
* @return queued primitive or NULL
*/
struct l1sched_ts_prim *l1sched_prim_push(struct trx_instance *trx,
+ enum l1sched_ts_prim_type type,
uint8_t chan_nr, uint8_t link_id,
const uint8_t *pl, size_t pl_len)
{
@@ -101,7 +105,7 @@
return NULL;
}
- prim = prim_alloc(ts, pl_len, chan_nr, link_id);
+ prim = prim_alloc(ts, pl_len, type, chan_nr, link_id);
if (prim == NULL)
return NULL;
@@ -156,7 +160,7 @@
};
/* Allocate a new primitive */
- prim = prim_alloc(lchan, GSM_MACBLOCK_LEN,
+ prim = prim_alloc(lchan, GSM_MACBLOCK_LEN, L1SCHED_PRIM_DATA,
l1sched_lchan_desc[lchan->type].chan_nr,
L1SCHED_CH_LID_SACCH);
OSMO_ASSERT(prim != NULL);
--
To view, visit
https://gerrit.osmocom.org/c/osmocom-bb/+/28552
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: I84597d44ea7d74b8840a919ecb09988ba1980a73
Gerrit-Change-Number: 28552
Gerrit-PatchSet: 4
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-MessageType: merged