diff --git a/src/host/trxcon/sched_lchan_desc.c b/src/host/trxcon/sched_lchan_desc.c index 2c3c3b2ee..b6a72b39c 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 6a6848971..abbd480c5 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 + * (C) 2018-2021 by Vadim Yanitskiy + * 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 */ + 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; - 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; - - 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 fe5821ba7..25e1b440b 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 + * (C) 2017-2021 by Vadim Yanitskiy + * 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 c5362f0b2..1e38e963f 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 + * (C) 2017-2021 by Vadim Yanitskiy + * 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 */ + 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; - 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; - - 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 b6f070826..6a5c47149 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 + * (C) 2018-2021 by Vadim Yanitskiy * (C) 2018 by Harald Welte + * 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 */ + 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; - LOGP(DSCHD, LOGL_DEBUG, "Transmitting %s fn=%u ts=%u burst=%u\n", - lchan_desc->name, fn, ts->index, bid); - - /* 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 a0b61adc8..41677ec1b 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 + * (C) 2017-2021 by Vadim Yanitskiy + * 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 */ + 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; - 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; - - 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 91310c09e..adcf198bd 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 fb7ecd495..74b41e35f 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 716fd23cd..c4561cea0 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 2fafa56a0..fa66d4a72 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);