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/.
Vadim Yanitskiy gerrit-no-reply at lists.osmocom.orgReview at https://gerrit.osmocom.org/7023 WIP: host/trxcon/scheduler: add PDTCH channel support Change-Id: I1176576f54c1d68e79cc6ac37d61a9033f7018dd --- M src/host/trxcon/Makefile.am M src/host/trxcon/sched_lchan_desc.c A src/host/trxcon/sched_lchan_pdtch.c M src/host/trxcon/sched_trx.h 4 files changed, 216 insertions(+), 3 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/23/7023/1 diff --git a/src/host/trxcon/Makefile.am b/src/host/trxcon/Makefile.am index c9cc170..c5ed3c8 100644 --- a/src/host/trxcon/Makefile.am +++ b/src/host/trxcon/Makefile.am @@ -32,6 +32,7 @@ # Scheduler trxcon_SOURCES += \ sched_lchan_common.c \ + sched_lchan_pdtch.c \ sched_lchan_desc.c \ sched_lchan_xcch.c \ sched_lchan_tchf.c \ diff --git a/src/host/trxcon/sched_lchan_desc.c b/src/host/trxcon/sched_lchan_desc.c index 390b1ef..c330259 100644 --- a/src/host/trxcon/sched_lchan_desc.c +++ b/src/host/trxcon/sched_lchan_desc.c @@ -29,10 +29,7 @@ #define LID_SACCH 0x40 /* TODO: implement */ -#define tx_pdtch_fn NULL #define tx_tchh_fn NULL - -#define rx_pdtch_fn NULL #define rx_tchh_fn NULL /* Forward declaration of handlers */ @@ -57,6 +54,13 @@ int tx_tchf_fn(struct trx_instance *trx, struct trx_ts *ts, struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid); +int rx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts, + struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid, + sbit_t *bits, int8_t rssi, float toa); + +int tx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts, + struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid); + const struct trx_lchan_desc trx_lchan_desc[_TRX_CHAN_MAX] = { { TRXC_IDLE, "IDLE", diff --git a/src/host/trxcon/sched_lchan_pdtch.c b/src/host/trxcon/sched_lchan_pdtch.c new file mode 100644 index 0000000..eb98509 --- /dev/null +++ b/src/host/trxcon/sched_lchan_pdtch.c @@ -0,0 +1,205 @@ +/* + * OsmocomBB <-> SDR connection bridge + * TDMA scheduler: handlers for DL / UL bursts on logical channels + * + * (C) 2018 by Vadim Yanitskiy <axilirator at gmail.com> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <errno.h> +#include <string.h> +#include <stdint.h> + +#include <osmocom/core/logging.h> +#include <osmocom/core/bits.h> + +#include <osmocom/gsm/gsm_utils.h> +#include <osmocom/gsm/protocol/gsm_04_08.h> +#include <osmocom/coding/gsm0503_coding.h> + +#include "l1ctl_proto.h" +#include "scheduler.h" +#include "sched_trx.h" +#include "logging.h" +#include "trx_if.h" +#include "trxcon.h" +#include "l1ctl.h" + +int rx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts, + struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid, + sbit_t *bits, int8_t rssi, float toa) +{ + const struct trx_lchan_desc *lchan_desc; + uint8_t l2[GPRS_L2_MAX_LEN], *mask; + int n_errors, n_bits_total, rc; + sbit_t *buffer, *offset; + uint32_t *first_fn; + size_t l2_len; + + /* Set up pointers */ + lchan_desc = &trx_lchan_desc[lchan->type]; + first_fn = &lchan->rx_first_fn; + mask = &lchan->rx_burst_mask; + buffer = lchan->rx_bursts; + + LOGP(DSCHD, LOGL_DEBUG, "Packet data received on %s: " + "fn=%u ts=%u bid=%u\n", lchan_desc->name, fn, ts->index, bid); + + /* Reset internal state */ + if (bid == 0) { + /* Clean up old measurements */ + memset(&lchan->meas, 0x00, sizeof(lchan->meas)); + + *first_fn = fn; + *mask = 0x0; + } + + /* Update mask */ + *mask |= (1 << bid); + + /* Update measurements */ + lchan->meas.rssi_sum += rssi; + lchan->meas.toa_sum += toa; + lchan->meas.rssi_num++; + lchan->meas.toa_num++; + + /* Copy burst to buffer of 4 bursts */ + offset = buffer + bid * 116; + memcpy(offset, bits + 3, 58); + memcpy(offset + 58, bits + 87, 58); + + /* Wait until complete set of bursts */ + if (bid != 3) + return 0; + + /* Check for complete set of bursts */ + if ((*mask & 0xf) != 0xf) { + LOGP(DSCHD, LOGL_ERROR, "Received incomplete data frame at " + "fn=%u (%u/%u) for %s\n", *first_fn, + (*first_fn) % ts->mf_layout->period, + ts->mf_layout->period, + lchan_desc->name); + + return -1; + } + + /* Attempt to decode */ + rc = gsm0503_pdtch_decode(l2, buffer, + NULL, &n_errors, &n_bits_total); + if (rc < 0) { + LOGP(DSCHD, LOGL_ERROR, "Received bad packet data frame " + "at fn=%u (%u/%u) for %s\n", *first_fn, + (*first_fn) % ts->mf_layout->period, + ts->mf_layout->period, + lchan_desc->name); + } + + /* Determine L2 length */ + l2_len = rc > 0 ? rc : 0; + + /* Send a L2 frame to the higher layers */ + sched_send_data_ind(trx, ts, lchan, + l2, l2_len, rc < 0, n_errors); + + return 0; +} + + +int tx_pdtch_fn(struct trx_instance *trx, struct trx_ts *ts, + struct trx_lchan_state *lchan, uint32_t fn, uint8_t bid) +{ + const struct trx_lchan_desc *lchan_desc; + ubit_t burst[GSM_BURST_LEN]; + ubit_t *buffer, *offset; + const uint8_t *tsc; + uint8_t *mask; + int rc; + + /* Set up pointers */ + lchan_desc = &trx_lchan_desc[lchan->type]; + mask = &lchan->tx_burst_mask; + buffer = lchan->tx_bursts; + + if (bid > 0) { + /* If we have encoded bursts */ + if (*mask) + goto send_burst; + else + return 0; + } + + /* Encode payload */ + rc = gsm0503_pdtch_encode(buffer, lchan->prim->payload, + lchan->prim->payload_len); + if (rc) { + LOGP(DSCHD, LOGL_ERROR, "Failed to encode L2 payload\n"); + + /* Forget this primitive */ + sched_prim_drop(lchan); + + return -EINVAL; + } + +send_burst: + /* Determine which burst should be sent */ + offset = buffer + bid * 116; + + /* Update mask */ + *mask |= (1 << 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; + + return rc; + } + + /* If we have sent the last (4/4) burst */ + if ((*mask & 0x0f) == 0x0f) { + /* Confirm data / traffic sending */ + sched_send_data_conf(trx, ts, lchan, fn, + lchan->prim->payload_len); + + /* Forget processed primitive */ + sched_prim_drop(lchan); + + /* Reset mask */ + *mask = 0x00; + } + + return 0; +} diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h index b01624c..4597e17 100644 --- a/src/host/trxcon/sched_trx.h +++ b/src/host/trxcon/sched_trx.h @@ -17,6 +17,9 @@ #define GPRS_BURST_LEN GSM_BURST_LEN #define EDGE_BURST_LEN 444 +#define GPRS_L2_MAX_LEN 54 +#define EDGE_L2_MAX_LEN 155 + #define TRX_CH_FLAG_PDCH (1 << 0) #define TRX_CH_FLAG_AUTO (1 << 1) #define TRX_TS_COUNT 8 -- To view, visit https://gerrit.osmocom.org/7023 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1176576f54c1d68e79cc6ac37d61a9033f7018dd Gerrit-PatchSet: 1 Gerrit-Project: osmocom-bb Gerrit-Branch: fixeria/trx Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com>