summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2021-06-14 23:14:34 +0200
committerVadim Yanitskiy <vyanitskiy@sysmocom.de>2021-06-16 15:55:32 +0200
commit529d54b13a308978188d0738e9979d35bee11031 (patch)
tree5dd4975bbe8b9812610e9629e9a5ce4f18d61193
parentc652349b4a771189f8787e11764a41916e3004b5 (diff)
trxcon/scheduler: introduce and use struct sched_burst_req
Similar to what we do in osmo-bts-trx, group everything related to an Uplink burst into a structure. Pass a pointer to this structure to the logical channel handlers. This makes the code easier to read, and facilitates sending NOPE indications to the transceiver (will be introduced in the upcoming patch). Get rid of sched_trx_handle_tx_burst(), and instead just call sched_trx_a5_burst_enc() directly from sched_frame_clck_cb(). Change-Id: Id45b27180c233fdc42ae1ef0b195554dd299a056 Related: SYS#5313, OS#1569
-rw-r--r--src/host/trxcon/sched_lchan_desc.c15
-rw-r--r--src/host/trxcon/sched_lchan_pdtch.c42
-rw-r--r--src/host/trxcon/sched_lchan_rach.c29
-rw-r--r--src/host/trxcon/sched_lchan_tchf.c42
-rw-r--r--src/host/trxcon/sched_lchan_tchh.c35
-rw-r--r--src/host/trxcon/sched_lchan_xcch.c42
-rw-r--r--src/host/trxcon/sched_trx.c54
-rw-r--r--src/host/trxcon/sched_trx.h22
-rw-r--r--src/host/trxcon/trx_if.c23
-rw-r--r--src/host/trxcon/trx_if.h4
10 files changed, 146 insertions, 162 deletions
diff --git a/src/host/trxcon/sched_lchan_desc.c b/src/host/trxcon/sched_lchan_desc.c
index 2c3c3b2e..b6a72b39 100644
--- a/src/host/trxcon/sched_lchan_desc.c
+++ b/src/host/trxcon/sched_lchan_desc.c
@@ -34,35 +34,40 @@ int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
const sbit_t *bits, const struct trx_meas_set *meas);
int tx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
- struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid);
+ struct trx_lchan_state *lchan,
+ struct sched_burst_req *br);
int rx_sch_fn(struct trx_instance *trx, struct trx_ts *ts,
struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid,
const sbit_t *bits, const struct trx_meas_set *meas);
int tx_rach_fn(struct trx_instance *trx, struct trx_ts *ts,
- struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid);
+ struct trx_lchan_state *lchan,
+ struct sched_burst_req *br);
int rx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts,
struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid,
const sbit_t *bits, const struct trx_meas_set *meas);
int tx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts,
- struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid);
+ struct trx_lchan_state *lchan,
+ struct sched_burst_req *br);
int rx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts,
struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid,
const sbit_t *bits, const struct trx_meas_set *meas);
int tx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts,
- struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid);
+ struct trx_lchan_state *lchan,
+ struct sched_burst_req *br);
int rx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts,
struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid,
const sbit_t *bits, const struct trx_meas_set *meas);
int tx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts,
- struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid);
+ struct trx_lchan_state *lchan,
+ struct sched_burst_req *br);
const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = {
[TRXC_IDLE] = {
diff --git a/src/host/trxcon/sched_lchan_pdtch.c b/src/host/trxcon/sched_lchan_pdtch.c
index 6a684897..abbd480c 100644
--- a/src/host/trxcon/sched_lchan_pdtch.c
+++ b/src/host/trxcon/sched_lchan_pdtch.c
@@ -2,7 +2,8 @@
* OsmocomBB <-> SDR connection bridge
* TDMA scheduler: handlers for DL / UL bursts on logical channels
*
- * (C) 2018-2020 by Vadim Yanitskiy <axilirator@gmail.com>
+ * (C) 2018-2021 by Vadim Yanitskiy <axilirator@gmail.com>
+ * Contributions by sysmocom - s.f.m.c. GmbH
*
* All Rights Reserved
*
@@ -117,10 +118,10 @@ int rx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts,
int tx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts,
- struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid)
+ struct trx_lchan_state *lchan,
+ struct sched_burst_req *br)
{
const struct trx_lchan_desc *lchan_desc;
- ubit_t burst[GSM_BURST_LEN];
ubit_t *buffer, *offset;
const uint8_t *tsc;
uint8_t *mask;
@@ -131,7 +132,7 @@ int tx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts,
mask = &lchan->tx_burst_mask;
buffer = lchan->tx_bursts;
- if (bid > 0) {
+ if (br->bid > 0) {
/* If we have encoded bursts */
if (*mask)
goto send_burst;
@@ -155,40 +156,29 @@ int tx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts,
send_burst:
/* Determine which burst should be sent */
- offset = buffer + bid * 116;
+ offset = buffer + br->bid * 116;
/* Update mask */
- *mask |= (1 << bid);
+ *mask |= (1 << br->bid);
/* Choose proper TSC */
tsc = sched_nb_training_bits[trx->tsc];
/* Compose a new burst */
- memset(burst, 0, 3); /* TB */
- memcpy(burst + 3, offset, 58); /* Payload 1/2 */
- memcpy(burst + 61, tsc, 26); /* TSC */
- memcpy(burst + 87, offset + 58, 58); /* Payload 2/2 */
- memset(burst + 145, 0, 3); /* TB */
-
- LOGP(DSCHD, LOGL_DEBUG, "Transmitting %s fn=%u ts=%u burst=%u\n",
- lchan_desc->name, fn, ts->index, bid);
-
- /* Forward burst to scheduler */
- rc = sched_trx_handle_tx_burst(trx, ts, lchan, fn, burst);
- if (rc) {
- /* Forget this primitive */
- sched_prim_drop(lchan);
+ memset(br->burst, 0, 3); /* TB */
+ memcpy(br->burst + 3, offset, 58); /* Payload 1/2 */
+ memcpy(br->burst + 61, tsc, 26); /* TSC */
+ memcpy(br->burst + 87, offset + 58, 58); /* Payload 2/2 */
+ memset(br->burst + 145, 0, 3); /* TB */
+ br->burst_len = GSM_BURST_LEN;
- /* Reset mask */
- *mask = 0x00;
-
- return rc;
- }
+ LOGP(DSCHD, LOGL_DEBUG, "Scheduled %s fn=%u ts=%u burst=%u\n",
+ lchan_desc->name, br->fn, ts->index, br->bid);
/* If we have sent the last (4/4) burst */
if ((*mask & 0x0f) == 0x0f) {
/* Confirm data / traffic sending */
- sched_send_dt_conf(trx, ts, lchan, fn, true);
+ sched_send_dt_conf(trx, ts, lchan, br->fn, true);
/* Forget processed primitive */
sched_prim_drop(lchan);
diff --git a/src/host/trxcon/sched_lchan_rach.c b/src/host/trxcon/sched_lchan_rach.c
index fe5821ba..25e1b440 100644
--- a/src/host/trxcon/sched_lchan_rach.c
+++ b/src/host/trxcon/sched_lchan_rach.c
@@ -2,7 +2,8 @@
* OsmocomBB <-> SDR connection bridge
* TDMA scheduler: handlers for DL / UL bursts on logical channels
*
- * (C) 2017-2019 by Vadim Yanitskiy <axilirator@gmail.com>
+ * (C) 2017-2021 by Vadim Yanitskiy <axilirator@gmail.com>
+ * Contributions by sysmocom - s.f.m.c. GmbH
*
* All Rights Reserved
*
@@ -77,13 +78,13 @@ static struct value_string rach_synch_seq_names[] = {
/* Obtain a to-be-transmitted RACH burst */
int tx_rach_fn(struct trx_instance *trx, struct trx_ts *ts,
- struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid)
+ struct trx_lchan_state *lchan,
+ struct sched_burst_req *br)
{
struct l1ctl_ext_rach_req *ext_req = NULL;
struct l1ctl_rach_req *req = NULL;
enum rach_synch_seq_t synch_seq;
- uint8_t burst[GSM_BURST_LEN];
- uint8_t *burst_ptr = burst;
+ uint8_t *burst_ptr = br->burst;
uint8_t payload[36];
int i, rc;
@@ -155,27 +156,19 @@ int tx_rach_fn(struct trx_instance *trx, struct trx_ts *ts,
burst_ptr += RACH_PAYLOAD_LEN;
/* BN85-156: tail bits & extended guard period */
- memset(burst_ptr, 0, burst + GSM_BURST_LEN - burst_ptr);
+ memset(burst_ptr, 0, br->burst + GSM_BURST_LEN - burst_ptr);
+ br->burst_len = GSM_BURST_LEN;
- LOGP(DSCHD, LOGL_NOTICE, "Transmitting %s RACH (%s) on fn=%u, tn=%u, lchan=%s\n",
+ LOGP(DSCHD, LOGL_NOTICE, "Scheduled %s RACH (%s) on fn=%u, tn=%u, lchan=%s\n",
PRIM_IS_RACH11(lchan->prim) ? "extended (11-bit)" : "regular (8-bit)",
- get_value_string(rach_synch_seq_names, synch_seq), fn,
+ get_value_string(rach_synch_seq_names, synch_seq), br->fn,
ts->index, trx_lchan_desc[lchan->type].name);
- /* Forward burst to scheduler */
- rc = sched_trx_handle_tx_burst(trx, ts, lchan, fn, burst);
- if (rc) {
- /* Forget this primitive */
- sched_prim_drop(lchan);
-
- return rc;
- }
-
/* Confirm RACH request */
- l1ctl_tx_rach_conf(trx->l1l, trx->band_arfcn, fn);
+ l1ctl_tx_rach_conf(trx->l1l, trx->band_arfcn, br->fn);
/* Optional GSMTAP logging */
- sched_gsmtap_send(lchan->type, fn, ts->index,
+ sched_gsmtap_send(lchan->type, br->fn, ts->index,
trx->band_arfcn | ARFCN_UPLINK, 0, 0,
PRIM_IS_RACH11(lchan->prim) ? (uint8_t *) &ext_req->ra11 : &req->ra,
PRIM_IS_RACH11(lchan->prim) ? 2 : 1);
diff --git a/src/host/trxcon/sched_lchan_tchf.c b/src/host/trxcon/sched_lchan_tchf.c
index c5362f0b..1e38e963 100644
--- a/src/host/trxcon/sched_lchan_tchf.c
+++ b/src/host/trxcon/sched_lchan_tchf.c
@@ -2,7 +2,8 @@
* OsmocomBB <-> SDR connection bridge
* TDMA scheduler: handlers for DL / UL bursts on logical channels
*
- * (C) 2017-2020 by Vadim Yanitskiy <axilirator@gmail.com>
+ * (C) 2017-2021 by Vadim Yanitskiy <axilirator@gmail.com>
+ * Contributions by sysmocom - s.f.m.c. GmbH
*
* All Rights Reserved
*
@@ -173,10 +174,10 @@ bfi:
}
int tx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts,
- struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid)
+ struct trx_lchan_state *lchan,
+ struct sched_burst_req *br)
{
const struct trx_lchan_desc *lchan_desc;
- ubit_t burst[GSM_BURST_LEN];
ubit_t *buffer, *offset;
const uint8_t *tsc;
uint8_t *mask;
@@ -193,7 +194,7 @@ int tx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts,
goto send_burst;
/* Wait until a first burst in period */
- if (bid > 0)
+ if (br->bid > 0)
return 0;
/* Check the current TCH mode */
@@ -257,40 +258,29 @@ int tx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts,
send_burst:
/* Determine which burst should be sent */
- offset = buffer + bid * 116;
+ offset = buffer + br->bid * 116;
/* Update mask */
- *mask |= (1 << bid);
+ *mask |= (1 << br->bid);
/* Choose proper TSC */
tsc = sched_nb_training_bits[trx->tsc];
/* Compose a new burst */
- memset(burst, 0, 3); /* TB */
- memcpy(burst + 3, offset, 58); /* Payload 1/2 */
- memcpy(burst + 61, tsc, 26); /* TSC */
- memcpy(burst + 87, offset + 58, 58); /* Payload 2/2 */
- memset(burst + 145, 0, 3); /* TB */
-
- LOGP(DSCHD, LOGL_DEBUG, "Transmitting %s fn=%u ts=%u burst=%u\n",
- lchan_desc->name, fn, ts->index, bid);
+ memset(br->burst, 0, 3); /* TB */
+ memcpy(br->burst + 3, offset, 58); /* Payload 1/2 */
+ memcpy(br->burst + 61, tsc, 26); /* TSC */
+ memcpy(br->burst + 87, offset + 58, 58); /* Payload 2/2 */
+ memset(br->burst + 145, 0, 3); /* TB */
+ br->burst_len = GSM_BURST_LEN;
- /* Forward burst to scheduler */
- rc = sched_trx_handle_tx_burst(trx, ts, lchan, fn, burst);
- if (rc) {
- /* Forget this primitive */
- sched_prim_drop(lchan);
-
- /* Reset mask */
- *mask = 0x00;
-
- return rc;
- }
+ LOGP(DSCHD, LOGL_DEBUG, "Scheduled %s fn=%u ts=%u burst=%u\n",
+ lchan_desc->name, br->fn, ts->index, br->bid);
/* If we have sent the last (4/4) burst */
if (*mask == 0x0f) {
/* Confirm data / traffic sending */
- sched_send_dt_conf(trx, ts, lchan, fn, PRIM_IS_TCH(lchan->prim));
+ sched_send_dt_conf(trx, ts, lchan, br->fn, PRIM_IS_TCH(lchan->prim));
/* Forget processed primitive */
sched_prim_drop(lchan);
diff --git a/src/host/trxcon/sched_lchan_tchh.c b/src/host/trxcon/sched_lchan_tchh.c
index b6f07082..6a5c4714 100644
--- a/src/host/trxcon/sched_lchan_tchh.c
+++ b/src/host/trxcon/sched_lchan_tchh.c
@@ -2,8 +2,9 @@
* OsmocomBB <-> SDR connection bridge
* TDMA scheduler: handlers for DL / UL bursts on logical channels
*
- * (C) 2018-2020 by Vadim Yanitskiy <axilirator@gmail.com>
+ * (C) 2018-2021 by Vadim Yanitskiy <axilirator@gmail.com>
* (C) 2018 by Harald Welte <laforge@gnumonks.org>
+ * Contributions by sysmocom - s.f.m.c. GmbH
*
* All Rights Reserved
*
@@ -361,10 +362,10 @@ bfi:
}
int tx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts,
- struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid)
+ struct trx_lchan_state *lchan,
+ struct sched_burst_req *br)
{
const struct trx_lchan_desc *lchan_desc;
- ubit_t burst[GSM_BURST_LEN];
ubit_t *buffer, *offset;
const uint8_t *tsc;
uint8_t *mask;
@@ -376,7 +377,7 @@ int tx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts,
mask = &lchan->tx_burst_mask;
buffer = lchan->tx_bursts;
- if (bid > 0) {
+ if (br->bid > 0) {
/* Align to the first burst */
if (*mask == 0x00)
return 0;
@@ -386,7 +387,7 @@ int tx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts,
if (*mask == 0x00) {
/* Align transmission of the first FACCH/H frame */
if (lchan->tch_mode == GSM48_CMODE_SIGN)
- if (!sched_tchh_facch_start(lchan->type, fn, 1))
+ if (!sched_tchh_facch_start(lchan->type, br->fn, 1))
return 0;
}
@@ -459,26 +460,24 @@ int tx_tchh_fn(struct trx_instance *trx, struct trx_ts *ts,
send_burst:
/* Determine which burst should be sent */
- offset = buffer + bid * 116;
+ offset = buffer + br->bid * 116;
/* Update mask */
- *mask |= (1 << bid);
+ *mask |= (1 << br->bid);
/* Choose proper TSC */
tsc = sched_nb_training_bits[trx->tsc];
/* Compose a new burst */
- memset(burst, 0, 3); /* TB */
- memcpy(burst + 3, offset, 58); /* Payload 1/2 */
- memcpy(burst + 61, tsc, 26); /* TSC */
- memcpy(burst + 87, offset + 58, 58); /* Payload 2/2 */
- memset(burst + 145, 0, 3); /* TB */
-
- LOGP(DSCHD, LOGL_DEBUG, "Transmitting %s fn=%u ts=%u burst=%u\n",
- lchan_desc->name, fn, ts->index, bid);
+ memset(br->burst, 0, 3); /* TB */
+ memcpy(br->burst + 3, offset, 58); /* Payload 1/2 */
+ memcpy(br->burst + 61, tsc, 26); /* TSC */
+ memcpy(br->burst + 87, offset + 58, 58); /* Payload 2/2 */
+ memset(br->burst + 145, 0, 3); /* TB */
+ br->burst_len = GSM_BURST_LEN;
- /* Forward burst to transceiver */
- sched_trx_handle_tx_burst(trx, ts, lchan, fn, burst);
+ LOGP(DSCHD, LOGL_DEBUG, "Scheduled %s fn=%u ts=%u burst=%u\n",
+ lchan_desc->name, br->fn, ts->index, br->bid);
/* In case of a FACCH/H frame, one block less */
if (lchan->ul_facch_blocks)
@@ -490,7 +489,7 @@ send_burst:
* confirm data / traffic sending
*/
if (!lchan->ul_facch_blocks)
- sched_send_dt_conf(trx, ts, lchan, fn,
+ sched_send_dt_conf(trx, ts, lchan, br->fn,
PRIM_IS_TCH(lchan->prim));
/* Forget processed primitive */
diff --git a/src/host/trxcon/sched_lchan_xcch.c b/src/host/trxcon/sched_lchan_xcch.c
index a0b61adc..41677ec1 100644
--- a/src/host/trxcon/sched_lchan_xcch.c
+++ b/src/host/trxcon/sched_lchan_xcch.c
@@ -2,7 +2,8 @@
* OsmocomBB <-> SDR connection bridge
* TDMA scheduler: handlers for DL / UL bursts on logical channels
*
- * (C) 2017-2020 by Vadim Yanitskiy <axilirator@gmail.com>
+ * (C) 2017-2021 by Vadim Yanitskiy <axilirator@gmail.com>
+ * Contributions by sysmocom - s.f.m.c. GmbH
*
* All Rights Reserved
*
@@ -119,10 +120,10 @@ int rx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
}
int tx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
- struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid)
+ struct trx_lchan_state *lchan,
+ struct sched_burst_req *br)
{
const struct trx_lchan_desc *lchan_desc;
- ubit_t burst[GSM_BURST_LEN];
ubit_t *buffer, *offset;
const uint8_t *tsc;
uint8_t *mask;
@@ -133,7 +134,7 @@ int tx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
mask = &lchan->tx_burst_mask;
buffer = lchan->tx_bursts;
- if (bid > 0) {
+ if (br->bid > 0) {
/* If we have encoded bursts */
if (*mask)
goto send_burst;
@@ -165,40 +166,29 @@ int tx_data_fn(struct trx_instance *trx, struct trx_ts *ts,
send_burst:
/* Determine which burst should be sent */
- offset = buffer + bid * 116;
+ offset = buffer + br->bid * 116;
/* Update mask */
- *mask |= (1 << bid);
+ *mask |= (1 << br->bid);
/* Choose proper TSC */
tsc = sched_nb_training_bits[trx->tsc];
/* Compose a new burst */
- memset(burst, 0, 3); /* TB */
- memcpy(burst + 3, offset, 58); /* Payload 1/2 */
- memcpy(burst + 61, tsc, 26); /* TSC */
- memcpy(burst + 87, offset + 58, 58); /* Payload 2/2 */
- memset(burst + 145, 0, 3); /* TB */
-
- LOGP(DSCHD, LOGL_DEBUG, "Transmitting %s fn=%u ts=%u burst=%u\n",
- lchan_desc->name, fn, ts->index, bid);
-
- /* Forward burst to scheduler */
- rc = sched_trx_handle_tx_burst(trx, ts, lchan, fn, burst);
- if (rc) {
- /* Forget this primitive */
- sched_prim_drop(lchan);
-
- /* Reset mask */
- *mask = 0x00;
+ memset(br->burst, 0, 3); /* TB */
+ memcpy(br->burst + 3, offset, 58); /* Payload 1/2 */
+ memcpy(br->burst + 61, tsc, 26); /* TSC */
+ memcpy(br->burst + 87, offset + 58, 58); /* Payload 2/2 */
+ memset(br->burst + 145, 0, 3); /* TB */
+ br->burst_len = GSM_BURST_LEN;
- return rc;
- }
+ LOGP(DSCHD, LOGL_DEBUG, "Scheduled %s fn=%u ts=%u burst=%u\n",
+ lchan_desc->name, br->fn, ts->index, br->bid);
/* If we have sent the last (4/4) burst */
if ((*mask & 0x0f) == 0x0f) {
/* Confirm data sending */
- sched_send_dt_conf(trx, ts, lchan, fn, false);
+ sched_send_dt_conf(trx, ts, lchan, br->fn, false);
/* Forget processed primitive */
sched_prim_drop(lchan);
diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c
index 91310c09..adcf198b 100644
--- a/src/host/trxcon/sched_trx.c
+++ b/src/host/trxcon/sched_trx.c
@@ -41,14 +41,18 @@
#include "trx_if.h"
#include "logging.h"
+static void sched_trx_a5_burst_enc(struct trx_lchan_state *lchan,
+ struct sched_burst_req *br);
+
static void sched_frame_clck_cb(struct trx_sched *sched)
{
struct trx_instance *trx = (struct trx_instance *) sched->data;
+ struct sched_burst_req br[TRX_TS_COUNT];
const struct trx_frame *frame;
struct trx_lchan_state *lchan;
trx_lchan_tx_func *handler;
enum trx_lchan_type chan;
- uint8_t offset, bid;
+ uint8_t offset;
struct trx_ts *ts;
int i;
@@ -59,6 +63,14 @@ static void sched_frame_clck_cb(struct trx_sched *sched)
/* Iterate over timeslot list */
for (i = 0; i < TRX_TS_COUNT; i++) {
+ /* Initialize the buffer for this timeslot */
+ br[i] = (struct sched_burst_req) {
+ .fn = fn,
+ .tn = i,
+ .pwr = trx->tx_power,
+ .burst_len = 0, /* NOPE.ind */
+ };
+
/* Timeslot is not allocated */
ts = trx->ts_list[i];
if (ts == NULL)
@@ -73,7 +85,7 @@ static void sched_frame_clck_cb(struct trx_sched *sched)
frame = ts->mf_layout->frames + offset;
/* Get required info from frame */
- bid = frame->ul_bid;
+ br[i].bid = frame->ul_bid;
chan = frame->ul_chan;
handler = trx_lchan_desc[chan].tx_fn;
@@ -120,8 +132,16 @@ static void sched_frame_clck_cb(struct trx_sched *sched)
handler = trx_lchan_desc[TRXC_RACH].tx_fn;
/* Poke lchan handler */
- handler(trx, ts, lchan, fn, bid);
+ handler(trx, ts, lchan, &br[i]);
+
+ /* Perform A5/X burst encryption if required */
+ if (lchan->a5.algo)
+ sched_trx_a5_burst_enc(lchan, &br[i]);
}
+
+ /* Send all bursts for this TDMA frame */
+ for (i = 0; i < ARRAY_SIZE(br); i++)
+ trx_if_tx_burst(trx, &br[i]);
}
int sched_trx_init(struct trx_instance *trx, uint32_t fn_advance)
@@ -602,18 +622,18 @@ static void sched_trx_a5_burst_dec(struct trx_lchan_state *lchan,
}
static void sched_trx_a5_burst_enc(struct trx_lchan_state *lchan,
- uint32_t fn, ubit_t *burst)
+ struct sched_burst_req *br)
{
ubit_t ks[114];
int i;
/* Generate keystream for an UL burst */
- osmo_a5(lchan->a5.algo, lchan->a5.key, fn, NULL, ks);
+ osmo_a5(lchan->a5.algo, lchan->a5.key, br->fn, NULL, ks);
/* Apply keystream over plaintext */
for (i = 0; i < 57; i++) {
- burst[i + 3] ^= ks[i];
- burst[i + 88] ^= ks[i + 57];
+ br->burst[i + 3] ^= ks[i];
+ br->burst[i + 88] ^= ks[i + 57];
}
}
@@ -764,26 +784,6 @@ int sched_trx_handle_rx_burst(struct trx_instance *trx, uint8_t tn,
return 0;
}
-int sched_trx_handle_tx_burst(struct trx_instance *trx,
- struct trx_ts *ts, struct trx_lchan_state *lchan,
- uint32_t fn, ubit_t *bits)
-{
- int rc;
-
- /* Perform A5/X burst encryption if required */
- if (lchan->a5.algo)
- sched_trx_a5_burst_enc(lchan, fn, bits);
-
- /* Forward burst to transceiver */
- rc = trx_if_tx_burst(trx, ts->index, fn, trx->tx_power, bits);
- if (rc) {
- LOGP(DSCHD, LOGL_ERROR, "Could not send burst to transceiver\n");
- return rc;
- }
-
- return 0;
-}
-
#define MEAS_HIST_FIRST(hist) \
(&hist->buf[0])
#define MEAS_HIST_LAST(hist) \
diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h
index fb7ecd49..74b41e35 100644
--- a/src/host/trxcon/sched_trx.h
+++ b/src/host/trxcon/sched_trx.h
@@ -97,14 +97,27 @@ enum trx_lchan_type {
_TRX_CHAN_MAX
};
+/* Represents a burst to be transmitted */
+struct sched_burst_req {
+ uint32_t fn;
+ uint8_t tn;
+ uint8_t pwr;
+
+ /* Internally used by the scheduler */
+ uint8_t bid;
+
+ ubit_t burst[EDGE_BURST_LEN];
+ size_t burst_len;
+};
+
typedef int trx_lchan_rx_func(struct trx_instance *trx,
struct trx_ts *ts, struct trx_lchan_state *lchan,
uint32_t fn, uint8_t bid, const sbit_t *bits,
const struct trx_meas_set *meas);
-typedef int trx_lchan_tx_func(struct trx_instance *trx,
- struct trx_ts *ts, struct trx_lchan_state *lchan,
- uint32_t fn, uint8_t bid);
+typedef int trx_lchan_tx_func(struct trx_instance *trx, struct trx_ts *ts,
+ struct trx_lchan_state *lchan,
+ struct sched_burst_req *br);
struct trx_lchan_desc {
/*! \brief Human-readable name */
@@ -366,9 +379,6 @@ void sched_prim_flush_queue(struct llist_head *list);
int sched_trx_handle_rx_burst(struct trx_instance *trx, uint8_t tn,
uint32_t fn, sbit_t *bits, uint16_t nbits,
const struct trx_meas_set *meas);
-int sched_trx_handle_tx_burst(struct trx_instance *trx,
- struct trx_ts *ts, struct trx_lchan_state *lchan,
- uint32_t fn, ubit_t *bits);
/* Shared declarations for lchan handlers */
extern const uint8_t sched_nb_training_bits[8][26];
diff --git a/src/host/trxcon/trx_if.c b/src/host/trxcon/trx_if.c
index 716fd23c..c4561cea 100644
--- a/src/host/trxcon/trx_if.c
+++ b/src/host/trxcon/trx_if.c
@@ -629,10 +629,14 @@ static int trx_data_rx_cb(struct osmo_fd *ofd, unsigned int what)
return 0;
}
-int trx_if_tx_burst(struct trx_instance *trx, uint8_t tn, uint32_t fn,
- uint8_t pwr, const ubit_t *bits)
+int trx_if_tx_burst(struct trx_instance *trx,
+ const struct sched_burst_req *br)
{
uint8_t buf[TRXD_BUF_SIZE];
+ size_t length;
+
+ if (br->burst_len == 0)
+ return 0;
/**
* We must be sure that we have clock,
@@ -649,17 +653,20 @@ int trx_if_tx_burst(struct trx_instance *trx, uint8_t tn, uint32_t fn,
}
#endif
- LOGP(DTRXD, LOGL_DEBUG, "TX burst tn=%u fn=%u pwr=%u\n", tn, fn, pwr);
+ LOGP(DTRXD, LOGL_DEBUG, "TX burst tn=%u fn=%u pwr=%u\n",
+ br->tn, br->fn, br->pwr);
- buf[0] = tn;
- osmo_store32be(fn, buf + 1);
- buf[5] = pwr;
+ buf[0] = br->tn;
+ osmo_store32be(br->fn, buf + 1);
+ buf[5] = br->pwr;
+ length = 6;
/* Copy ubits {0,1} */
- memcpy(buf + 6, bits, 148);
+ memcpy(buf + 6, br->burst, br->burst_len);
+ length += br->burst_len;
/* Send data to transceiver */
- send(trx->trx_ofd_data.fd, buf, 154, 0);
+ send(trx->trx_ofd_data.fd, buf, length, 0);
return 0;
}
diff --git a/src/host/trxcon/trx_if.h b/src/host/trxcon/trx_if.h
index 2fafa56a..fa66d4a7 100644
--- a/src/host/trxcon/trx_if.h
+++ b/src/host/trxcon/trx_if.h
@@ -79,5 +79,5 @@ int trx_if_cmd_setfh(struct trx_instance *trx, uint8_t hsn,
int trx_if_cmd_measure(struct trx_instance *trx,
uint16_t band_arfcn_start, uint16_t band_arfcn_stop);
-int trx_if_tx_burst(struct trx_instance *trx, uint8_t tn, uint32_t fn,
- uint8_t pwr, const ubit_t *bits);
+int trx_if_tx_burst(struct trx_instance *trx,
+ const struct sched_burst_req *br);