This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
ttsou gerrit-no-reply at lists.osmocom.orgReview at https://gerrit.osmocom.org/483 trx: Enable EGPRS handling through burst lengths Existing interfaces are coded with the implicit expectation of using a burst sequence length of 148, which is constant with GSM and GPRS. That changes with EGPRS, where the burst length may be 444 due to the use of 8-PSK instead of GMSK modulation. Setup the interface to accept and return a length value with the burst sequence. This allows 444 length bit vectors to/from the EGPRS decoder/encoder. Length is explicitly used as a identifier for 8-PSK vs. GMSK modulated sequences. Change-Id: I90b46b46b11b6ce280e7f8232d5a2fccec2d4f18 Signed-off-by: Tom Tsou <tom.tsou at ettus.com> --- M include/osmo-bts/scheduler.h M include/osmo-bts/scheduler_backend.h M src/common/scheduler.c M src/osmo-bts-trx/gsm0503_coding.c M src/osmo-bts-trx/scheduler_trx.c M src/osmo-bts-trx/trx_if.c M src/osmo-bts-trx/trx_if.h 7 files changed, 174 insertions(+), 89 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/83/483/1 diff --git a/include/osmo-bts/scheduler.h b/include/osmo-bts/scheduler.h index b11e6f1..265d1e2 100644 --- a/include/osmo-bts/scheduler.h +++ b/include/osmo-bts/scheduler.h @@ -151,7 +151,7 @@ /*! \brief handle an UL burst received by PHY */ int trx_sched_ul_burst(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - sbit_t *bits, int8_t rssi, float toa); + sbit_t *bits, uint16_t nbits, int8_t rssi, float toa); /*! \brief set multiframe scheduler to given physical channel config */ int trx_sched_set_pchan(struct l1sched_trx *l1t, uint8_t tn, diff --git a/include/osmo-bts/scheduler_backend.h b/include/osmo-bts/scheduler_backend.h index 9c0361d..68f0c60 100644 --- a/include/osmo-bts/scheduler_backend.h +++ b/include/osmo-bts/scheduler_backend.h @@ -5,12 +5,12 @@ typedef ubit_t *trx_sched_dl_func(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, enum trx_chan_type chan, - uint8_t bid); + uint8_t bid, uint16_t *nbits); typedef int trx_sched_ul_func(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, enum trx_chan_type chan, - uint8_t bid, sbit_t *bits, int8_t rssi, - float toa); + uint8_t bid, sbit_t *bits, uint16_t nbits, + int8_t rssi, float toa); struct trx_chan_desc { /*! \brief Is this on a PDCH (PS) ? */ @@ -49,35 +49,36 @@ enum trx_chan_type chan, uint8_t *tch, uint8_t tch_len); ubit_t *tx_idle_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid); + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits); ubit_t *tx_fcch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid); + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits); ubit_t *tx_sch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid); + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits); ubit_t *tx_data_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid); + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits); ubit_t *tx_pdtch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid); + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits); ubit_t *tx_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid); + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits); ubit_t *tx_tchh_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid); + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits); int rx_rach_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi, - float toa); + enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits, + int8_t rssi, float toa); int rx_data_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi, - float toa); + enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits, + int8_t rssi, float toa); int rx_pdtch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi, - float toa); + enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits, + int8_t rssi, float toa); int rx_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi, - float toa); + enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits, + int8_t rssi, float toa); int rx_tchh_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi, - float toa); + enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits, + int8_t rssi, float toa); -const ubit_t *_sched_dl_burst(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn); +const ubit_t *_sched_dl_burst(struct l1sched_trx *l1t, uint8_t tn, + uint32_t fn, uint16_t *nbits); int _sched_rts(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn); void _sched_act_rach_det(struct l1sched_trx *l1t, uint8_t tn, uint8_t ss, int activate); diff --git a/src/common/scheduler.c b/src/common/scheduler.c index 7c790cd..a7f40ed 100644 --- a/src/common/scheduler.c +++ b/src/common/scheduler.c @@ -1504,7 +1504,8 @@ } /* process downlink burst */ -const ubit_t *_sched_dl_burst(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn) +const ubit_t *_sched_dl_burst(struct l1sched_trx *l1t, uint8_t tn, + uint32_t fn, uint16_t *nbits) { struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn); struct l1sched_chan_state *l1cs; @@ -1529,11 +1530,14 @@ l1cs = &l1ts->chan_state[chan]; /* check if channel is active */ - if (!trx_chan_desc[chan].auto_active && !l1cs->active) - goto no_data; + if (!trx_chan_desc[chan].auto_active && !l1cs->active) { + if (nbits) + *nbits = 148; + goto no_data; + } /* get burst from function */ - bits = func(l1t, tn, fn, chan, bid); + bits = func(l1t, tn, fn, chan, bid, nbits); /* encrypt */ if (bits && l1cs->dl_encr_algo) { @@ -1562,7 +1566,7 @@ /* process uplink burst */ int trx_sched_ul_burst(struct l1sched_trx *l1t, uint8_t tn, uint32_t current_fn, - sbit_t *bits, int8_t rssi, float toa) + sbit_t *bits, uint16_t nbits, int8_t rssi, float toa) { struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn); struct l1sched_chan_state *l1cs; @@ -1623,12 +1627,12 @@ } } - func(l1t, tn, fn, chan, bid, bits, rssi, toa); + func(l1t, tn, fn, chan, bid, bits, nbits, rssi, toa); } else if (chan != TRXC_RACH && !l1cs->ho_rach_detect) { sbit_t spare[148]; memset(spare, 0, 148); - func(l1t, tn, fn, chan, bid, spare, -128, 0); + func(l1t, tn, fn, chan, bid, spare, 148, -128, 0); } next_frame: diff --git a/src/osmo-bts-trx/gsm0503_coding.c b/src/osmo-bts-trx/gsm0503_coding.c index 4aac986..e145ef6 100644 --- a/src/osmo-bts-trx/gsm0503_coding.c +++ b/src/osmo-bts-trx/gsm0503_coding.c @@ -1382,7 +1382,7 @@ gsm0503_xcch_burst_map(&iB[i * 114], &bursts[i * 116], hl_hn + i*2, hl_hn + i*2 + 1); - return 0; + return GSM0503_GPRS_BURSTS_NBITS; } diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c index 9a6a59c..6f79fdb 100644 --- a/src/osmo-bts-trx/scheduler_trx.c +++ b/src/osmo-bts-trx/scheduler_trx.c @@ -60,6 +60,8 @@ * Note that regular phones will not work when using this test! */ //#define TA_TEST +/* Maximum size of a EGPRS message in bytes */ +#define EGPRS_0503_MAX_BYTES 155 /* * TX on downlink @@ -67,19 +69,25 @@ /* an IDLE burst returns nothing. on C0 it is replaced by dummy burst */ ubit_t *tx_idle_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid) + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits) { LOGP(DL1C, LOGL_DEBUG, "Transmitting %s fn=%u ts=%u trx=%u\n", trx_chan_desc[chan].name, fn, tn, l1t->trx->nr); + + if (nbits) + *nbits = GSM_BURST_LEN; return NULL; } ubit_t *tx_fcch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid) + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits) { LOGP(DL1C, LOGL_DEBUG, "Transmitting %s fn=%u ts=%u trx=%u\n", trx_chan_desc[chan].name, fn, tn, l1t->trx->nr); + + if (nbits) + *nbits = GSM_BURST_LEN; /* BURST BYPASS */ @@ -87,9 +95,9 @@ } ubit_t *tx_sch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid) + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits) { - static ubit_t bits[148], burst[78]; + static ubit_t bits[GSM_BURST_LEN], burst[78]; uint8_t sb_info[4]; struct gsm_time t; uint8_t t3p, bsic; @@ -125,11 +133,14 @@ memcpy(bits + 106, burst + 39, 39); memset(bits + 145, 0, 3); + if (nbits) + *nbits = GSM_BURST_LEN; + return bits; } ubit_t *tx_data_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid) + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits) { struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn); struct gsm_bts_trx_ts *ts = &l1t->trx->ts[tn]; @@ -137,7 +148,7 @@ uint8_t chan_nr = trx_chan_desc[chan].chan_nr | tn; struct msgb *msg = NULL; /* make GCC happy */ ubit_t *burst, **bursts_p = &l1ts->chan_state[chan].dl_bursts; - static ubit_t bits[148]; + static ubit_t bits[GSM_BURST_LEN]; /* send burst, if we already got a frame */ if (bid > 0) { @@ -216,6 +227,9 @@ memcpy(bits + 87, burst + 58, 58); memset(bits + 145, 0, 3); + if (nbits) + *nbits = GSM_BURST_LEN; + LOGP(DL1C, LOGL_DEBUG, "Transmitting %s fn=%u ts=%u trx=%u burst=%u\n", trx_chan_desc[chan].name, fn, tn, l1t->trx->nr, bid); @@ -223,14 +237,14 @@ } ubit_t *tx_pdtch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid) + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits) { struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn); struct gsm_bts_trx_ts *ts = &l1t->trx->ts[tn]; struct msgb *msg = NULL; /* make GCC happy */ ubit_t *burst, **bursts_p = &l1ts->chan_state[chan].dl_bursts; - static ubit_t bits[148]; - int rc; + static ubit_t bits[EGPRS_PSK_BURST_LEN]; + int rc = 0; /* send burst, if we already got a frame */ if (bid > 0) { @@ -261,18 +275,29 @@ /* alloc burst memory, if not already */ if (!*bursts_p) { - *bursts_p = talloc_zero_size(tall_bts_ctx, 464); + *bursts_p = talloc_zero_size(tall_bts_ctx, + GSM0503_EGPRS_BURSTS_NBITS); if (!*bursts_p) return NULL; + } else { + talloc_realloc_size(tall_bts_ctx, *bursts_p, + GSM0503_EGPRS_BURSTS_NBITS); } /* encode bursts */ - rc = pdtch_encode(*bursts_p, msg->l2h, msg->tail - msg->l2h); + rc = pdtch_egprs_encode(*bursts_p, msg->l2h, msg->tail - msg->l2h); + if (rc < 0) + rc = pdtch_encode(*bursts_p, msg->l2h, msg->tail - msg->l2h); + + if (rc == GSM0503_GPRS_BURSTS_NBITS) { + talloc_realloc_size(tall_bts_ctx, *bursts_p, + GSM0503_GPRS_BURSTS_NBITS); + } /* check validity of message */ - if (rc) { + if (rc < 0) { LOGP(DL1C, LOGL_FATAL, "Prim invalid length, please FIX! " - "(len=%d)\n", rc); + "(len=%ld)\n", msg->tail - msg->l2h); /* free message */ msgb_free(msg); goto no_msg; @@ -283,12 +308,27 @@ send_burst: /* compose burst */ - burst = *bursts_p + bid * 116; - memset(bits, 0, 3); - memcpy(bits + 3, burst, 58); - memcpy(bits + 61, _sched_tsc[gsm_ts_tsc(ts)], 26); - memcpy(bits + 87, burst + 58, 58); - memset(bits + 145, 0, 3); + if (talloc_total_size(*bursts_p) == GSM0503_EGPRS_BURSTS_NBITS) { + burst = *bursts_p + bid * 348; + memset(bits, 1, 9); + memcpy(bits + 9, burst, 174); + memcpy(bits + 183, _sched_egprs_tsc[gsm_ts_tsc(ts)], 78); + memcpy(bits + 261, burst + 174, 174); + memset(bits + 435, 1, 9); + + if (nbits) + *nbits = EGPRS_PSK_BURST_LEN; + } else { + burst = *bursts_p + bid * 116; + memset(bits, 0, 3); + memcpy(bits + 3, burst, 58); + memcpy(bits + 61, _sched_tsc[gsm_ts_tsc(ts)], 26); + memcpy(bits + 87, burst + 58, 58); + memset(bits + 145, 0, 3); + + if (nbits) + *nbits = GSM_BURST_LEN; + } LOGP(DL1C, LOGL_DEBUG, "Transmitting %s fn=%u ts=%u trx=%u burst=%u\n", trx_chan_desc[chan].name, fn, tn, l1t->trx->nr, bid); @@ -528,7 +568,7 @@ } ubit_t *tx_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid) + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits) { struct msgb *msg_tch = NULL, *msg_facch = NULL; struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn); @@ -536,7 +576,7 @@ struct l1sched_chan_state *chan_state = &l1ts->chan_state[chan]; uint8_t tch_mode = chan_state->tch_mode; ubit_t *burst, **bursts_p = &chan_state->dl_bursts; - static ubit_t bits[148]; + static ubit_t bits[GSM_BURST_LEN]; /* send burst, if we already got a frame */ if (bid > 0) { @@ -600,6 +640,9 @@ memcpy(bits + 87, burst + 58, 58); memset(bits + 145, 0, 3); + if (nbits) + *nbits = GSM_BURST_LEN; + LOGP(DL1C, LOGL_DEBUG, "Transmitting %s fn=%u ts=%u trx=%u burst=%u\n", trx_chan_desc[chan].name, fn, tn, l1t->trx->nr, bid); @@ -607,7 +650,7 @@ } ubit_t *tx_tchh_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid) + enum trx_chan_type chan, uint8_t bid, uint16_t *nbits) { struct msgb *msg_tch = NULL, *msg_facch = NULL; struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn); @@ -615,7 +658,7 @@ struct l1sched_chan_state *chan_state = &l1ts->chan_state[chan]; uint8_t tch_mode = chan_state->tch_mode; ubit_t *burst, **bursts_p = &chan_state->dl_bursts; - static ubit_t bits[148]; + static ubit_t bits[GSM_BURST_LEN]; /* send burst, if we already got a frame */ if (bid > 0) { @@ -696,6 +739,9 @@ memcpy(bits + 87, burst + 58, 58); memset(bits + 145, 0, 3); + if (nbits) + *nbits = GSM_BURST_LEN; + LOGP(DL1C, LOGL_DEBUG, "Transmitting %s fn=%u ts=%u trx=%u burst=%u\n", trx_chan_desc[chan].name, fn, tn, l1t->trx->nr, bid); @@ -708,8 +754,8 @@ */ int rx_rach_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi, - float toa) + enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits, + int8_t rssi, float toa) { uint8_t chan_nr; struct osmo_phsap_prim l1sap; @@ -751,8 +797,8 @@ /*! \brief a single burst was received by the PHY, process it */ int rx_data_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi, - float toa) + enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits, + int8_t rssi, float toa) { struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn); struct l1sched_chan_state *chan_state = &l1ts->chan_state[chan]; @@ -769,7 +815,7 @@ /* handle rach, if handover rach detection is turned on */ if (chan_state->ho_rach_detect == 1) - return rx_rach_fn(l1t, tn, fn, chan, bid, bits, rssi, toa); + return rx_rach_fn(l1t, tn, fn, chan, bid, bits, GSM_BURST_LEN, rssi, toa); LOGP(DL1C, LOGL_DEBUG, "Data received %s fn=%u ts=%u trx=%u bid=%u\n", trx_chan_desc[chan].name, fn, tn, l1t->trx->nr, bid); @@ -848,8 +894,8 @@ } int rx_pdtch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi, - float toa) + enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits, + int8_t rssi, float toa) { struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn); struct l1sched_chan_state *chan_state = &l1ts->chan_state[chan]; @@ -859,8 +905,8 @@ uint8_t *rssi_num = &chan_state->rssi_num; float *toa_sum = &chan_state->toa_sum; uint8_t *toa_num = &chan_state->toa_num; - uint8_t l2[54]; - int n_errors, n_bits_total; + uint8_t l2[EGPRS_0503_MAX_BYTES]; + int n_errors, n_bursts_bits, n_bits_total; int rc; LOGP(DL1C, LOGL_DEBUG, "PDTCH received %s fn=%u ts=%u trx=%u bid=%u\n", @@ -868,14 +914,15 @@ /* alloc burst memory, if not already */ if (!*bursts_p) { - *bursts_p = talloc_zero_size(tall_bts_ctx, 464); + *bursts_p = talloc_zero_size(tall_bts_ctx, + GSM0503_EGPRS_BURSTS_NBITS); if (!*bursts_p) return -ENOMEM; } /* clear burst */ if (bid == 0) { - memset(*bursts_p, 0, 464); + memset(*bursts_p, 0, GSM0503_EGPRS_BURSTS_NBITS); *mask = 0x0; *rssi_sum = 0; *rssi_num = 0; @@ -891,9 +938,17 @@ (*toa_num)++; /* copy burst to buffer of 4 bursts */ - burst = *bursts_p + bid * 116; - memcpy(burst, bits + 3, 58); - memcpy(burst + 58, bits + 87, 58); + if (nbits == EGPRS_PSK_BURST_LEN) { + burst = *bursts_p + bid * 348; + memcpy(burst, bits + 9, 174); + memcpy(burst + 174, bits + 261, 174); + n_bursts_bits = GSM0503_EGPRS_BURSTS_NBITS; + } else { + burst = *bursts_p + bid * 116; + memcpy(burst, bits + 3, 58); + memcpy(burst + 58, bits + 87, 58); + n_bursts_bits = GSM0503_GPRS_BURSTS_NBITS; + } /* wait until complete set of bursts */ if (bid != 3) @@ -908,8 +963,20 @@ } *mask = 0x0; - /* decode */ - rc = pdtch_decode(l2, *bursts_p, NULL, &n_errors, &n_bits_total); + /* + * Attempt to decode EGPRS bursts first. For 8-PSK EGPRS this is all we + * do. Attempt GPRS decoding on EGPRS failure. If the burst is GPRS, + * then we incur decoding overhead of 31 bits on the Type 3 EGPRS + * header, which is tolerable. + */ + rc = pdtch_egprs_decode(l2, *bursts_p, n_bursts_bits, + NULL, &n_errors, &n_bits_total); + + if ((nbits == GSM_BURST_LEN) && (rc < 0)) { + rc = pdtch_decode(l2, *bursts_p, NULL, + &n_errors, &n_bits_total); + } + /* Send uplnk measurement information to L2 */ l1if_process_meas_res(l1t->trx, tn, fn, trx_chan_desc[chan].chan_nr | tn, @@ -927,8 +994,8 @@ } int rx_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi, - float toa) + enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits, + int8_t rssi, float toa) { struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn); struct l1sched_chan_state *chan_state = &l1ts->chan_state[chan]; @@ -944,7 +1011,7 @@ /* handle rach, if handover rach detection is turned on */ if (chan_state->ho_rach_detect == 1) - return rx_rach_fn(l1t, tn, fn, chan, bid, bits, rssi, toa); + return rx_rach_fn(l1t, tn, fn, chan, bid, bits, GSM_BURST_LEN, rssi, toa); LOGP(DL1C, LOGL_DEBUG, "TCH/F received %s fn=%u ts=%u trx=%u bid=%u\n", trx_chan_desc[chan].name, fn, tn, l1t->trx->nr, bid); @@ -1083,8 +1150,8 @@ } int rx_tchh_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn, - enum trx_chan_type chan, uint8_t bid, sbit_t *bits, int8_t rssi, - float toa) + enum trx_chan_type chan, uint8_t bid, sbit_t *bits, uint16_t nbits, + int8_t rssi, float toa) { struct l1sched_ts *l1ts = l1sched_trx_get_ts(l1t, tn); struct l1sched_chan_state *chan_state = &l1ts->chan_state[chan]; @@ -1100,7 +1167,7 @@ /* handle rach, if handover rach detection is turned on */ if (chan_state->ho_rach_detect == 1) - return rx_rach_fn(l1t, tn, fn, chan, bid, bits, rssi, toa); + return rx_rach_fn(l1t, tn, fn, chan, bid, bits, GSM_BURST_LEN, rssi, toa); LOGP(DL1C, LOGL_DEBUG, "TCH/H received %s fn=%u ts=%u trx=%u bid=%u\n", trx_chan_desc[chan].name, fn, tn, l1t->trx->nr, bid); @@ -1263,6 +1330,7 @@ uint8_t tn; const ubit_t *bits; uint8_t gain; + uint16_t nbits; /* send time indication */ l1if_mph_time_ind(bts, fn); @@ -1288,13 +1356,13 @@ _sched_rts(l1t, tn, (fn + plink->u.osmotrx.rts_advance) % GSM_HYPERFRAME); /* get burst for FN */ - bits = _sched_dl_burst(l1t, tn, fn); + bits = _sched_dl_burst(l1t, tn, fn, &nbits); if (!bits) { /* if no bits, send no burst */ continue; } else gain = 0; - trx_if_data(l1h, tn, fn, gain, bits); + trx_if_data(l1h, tn, fn, gain, bits, nbits); } } diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c index b2766d0..b0917fd 100644 --- a/src/osmo-bts-trx/trx_if.c +++ b/src/osmo-bts-trx/trx_if.c @@ -50,6 +50,8 @@ int settsc_enabled = 0; int setbsic_enabled = 0; +#define TRX_MAX_BURST_LEN 512 + /* * socket */ @@ -406,19 +408,21 @@ static int trx_data_read_cb(struct osmo_fd *ofd, unsigned int what) { struct trx_l1h *l1h = ofd->data; - uint8_t buf[256]; + uint8_t buf[TRX_MAX_BURST_LEN]; int len; uint8_t tn; int8_t rssi; float toa = 0.0; uint32_t fn; - sbit_t bits[148]; - int i; + sbit_t bits[EGPRS_PSK_BURST_LEN]; + int i, burst_len = GSM_BURST_LEN; len = recv(ofd->fd, buf, sizeof(buf), 0); - if (len <= 0) + if (len <= 0) { return len; - if (len != 158) { + } else if (len == EGPRS_PSK_BURST_LEN + 10) { + burst_len = EGPRS_PSK_BURST_LEN; + } else if (len != GSM_BURST_LEN + 10) { LOGP(DTRX, LOGL_NOTICE, "Got data message with invalid lenght " "'%d'\n", len); return -EINVAL; @@ -429,7 +433,7 @@ toa = ((int16_t)(buf[6] << 8) | buf[7]) / 256.0F; /* copy and convert bits {254..0} to sbits {-127..127} */ - for (i = 0; i < 148; i++) { + for (i = 0; i < burst_len; i++) { if (buf[8 + i] == 255) bits[i] = -127; else @@ -457,15 +461,20 @@ fprintf(stderr, "%s\n", deb); #endif - trx_sched_ul_burst(&l1h->l1s, tn, fn, bits, rssi, toa); + trx_sched_ul_burst(&l1h->l1s, tn, fn, bits, burst_len, rssi, toa); return 0; } int trx_if_data(struct trx_l1h *l1h, uint8_t tn, uint32_t fn, uint8_t pwr, - const ubit_t *bits) + const ubit_t *bits, uint16_t nbits) { - uint8_t buf[256]; + uint8_t buf[TRX_MAX_BURST_LEN]; + + if ((nbits != GSM_BURST_LEN) && (nbits != EGPRS_PSK_BURST_LEN)) { + LOGP(DTRX, LOGL_ERROR, "Tx burst length %u invalid\n", nbits); + return -1; + } LOGP(DTRX, LOGL_DEBUG, "TX burst tn=%u fn=%u pwr=%u\n", tn, fn, pwr); @@ -477,12 +486,12 @@ buf[5] = pwr; /* copy ubits {0,1} */ - memcpy(buf + 6, bits, 148); + memcpy(buf + 6, bits, nbits); /* we must be sure that we have clock, and we have sent all control * data */ if (transceiver_available && llist_empty(&l1h->trx_ctrl_list)) { - send(l1h->trx_ofd_data.fd, buf, 154, 0); + send(l1h->trx_ofd_data.fd, buf, nbits + 6, 0); } else LOGP(DTRX, LOGL_DEBUG, "Ignoring TX data, transceiver " "offline.\n"); diff --git a/src/osmo-bts-trx/trx_if.h b/src/osmo-bts-trx/trx_if.h index 1ea0da9..229e252 100644 --- a/src/osmo-bts-trx/trx_if.h +++ b/src/osmo-bts-trx/trx_if.h @@ -1,6 +1,9 @@ #ifndef TRX_IF_H #define TRX_IF_H +#define GSM_BURST_LEN 148 +#define EGPRS_PSK_BURST_LEN 444 + extern int transceiver_available; extern const char *transceiver_ip; extern int settsc_enabled; @@ -28,7 +31,7 @@ int trx_if_cmd_handover(struct trx_l1h *l1h, uint8_t tn, uint8_t ss); int trx_if_cmd_nohandover(struct trx_l1h *l1h, uint8_t tn, uint8_t ss); int trx_if_data(struct trx_l1h *l1h, uint8_t tn, uint32_t fn, uint8_t pwr, - const ubit_t *bits); + const ubit_t *bits, uint16_t nbits); int trx_if_open(struct trx_l1h *l1h); void trx_if_flush(struct trx_l1h *l1h); void trx_if_close(struct trx_l1h *l1h); -- To view, visit https://gerrit.osmocom.org/483 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I90b46b46b11b6ce280e7f8232d5a2fccec2d4f18 Gerrit-PatchSet: 1 Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Owner: ttsou <tom at tsou.cc>