fixeria has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmocom-bb/+/30743 )
Change subject: trxcon: add initial GPRS L1 implementation - libl1gprs.la
......................................................................
trxcon: add initial GPRS L1 implementation - libl1gprs.la
Change-Id: I9567d64f9d00262e36147e8d7e541e5e246bda5f
Related: OS#5500
---
M src/host/trxcon/configure.ac
M src/host/trxcon/include/osmocom/bb/Makefile.am
A src/host/trxcon/include/osmocom/bb/l1gprs/Makefile.am
A src/host/trxcon/include/osmocom/bb/l1gprs/l1gprs.h
A src/host/trxcon/include/osmocom/bb/l1gprs/logging.h
M src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
M src/host/trxcon/include/osmocom/bb/trxcon/logging.h
M src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
M src/host/trxcon/src/Makefile.am
A src/host/trxcon/src/gprs.c
M src/host/trxcon/src/logging.c
M src/host/trxcon/src/trxcon_fsm.c
M src/host/trxcon/src/trxcon_inst.c
13 files changed, 294 insertions(+), 3 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/43/30743/1
diff --git a/src/host/trxcon/configure.ac b/src/host/trxcon/configure.ac
index 6508689..b22d1c8 100644
--- a/src/host/trxcon/configure.ac
+++ b/src/host/trxcon/configure.ac
@@ -16,6 +16,7 @@
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore)
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding)
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm)
+PKG_CHECK_MODULES(LIBOSMOGPRSRLCMAC, libosmo-gprs-rlcmac)
dnl checks for header files
AC_HEADER_STDC
@@ -63,6 +64,7 @@
include/osmocom/Makefile
include/osmocom/bb/Makefile
include/osmocom/bb/l1sched/Makefile
+ include/osmocom/bb/l1gprs/Makefile
include/osmocom/bb/trxcon/Makefile
src/Makefile
Makefile])
diff --git a/src/host/trxcon/include/osmocom/bb/Makefile.am
b/src/host/trxcon/include/osmocom/bb/Makefile.am
index c26db00..183f6a5 100644
--- a/src/host/trxcon/include/osmocom/bb/Makefile.am
+++ b/src/host/trxcon/include/osmocom/bb/Makefile.am
@@ -1,4 +1,5 @@
SUBDIRS = \
l1sched \
+ l1gprs \
trxcon \
$(NULL)
diff --git a/src/host/trxcon/include/osmocom/bb/l1gprs/Makefile.am
b/src/host/trxcon/include/osmocom/bb/l1gprs/Makefile.am
new file mode 100644
index 0000000..e14a44e
--- /dev/null
+++ b/src/host/trxcon/include/osmocom/bb/l1gprs/Makefile.am
@@ -0,0 +1,4 @@
+noinst_HEADERS = \
+ l1gprs.h \
+ logging.h \
+ $(NULL)
diff --git a/src/host/trxcon/include/osmocom/bb/l1gprs/l1gprs.h
b/src/host/trxcon/include/osmocom/bb/l1gprs/l1gprs.h
new file mode 100644
index 0000000..07e17d4
--- /dev/null
+++ b/src/host/trxcon/include/osmocom/bb/l1gprs/l1gprs.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+
+struct l1gprs_prim_data_ind {
+ uint32_t frame_nr;
+ size_t data_len;
+ const uint8_t *data;
+};
+
+struct l1gprs_grr_inst;
+
+struct l1gprs_pdch {
+ bool enabled;
+ uint8_t tn; /*!< Timeslot number */
+
+ /*! Backpointer to l1gprs_state we belong to */
+ struct l1gprs_grr_inst *grr;
+};
+
+struct l1gprs_grr_inst {
+ /*! PDCH state for each timeslot */
+ struct l1gprs_pdch pdch[8];
+ /*! Logging context (used as prefix for messages) */
+ const char *log_prefix;
+ /*! Some private data for API user */
+ void *priv;
+};
+
+struct l1gprs_grr_inst *l1gprs_grr_inst_alloc(void *ctx, const char *log_prefix, void
*priv);
+void l1gprs_grr_inst_free(struct l1gprs_grr_inst *grr);
+
+int l1gprs_pdch_enable(struct l1gprs_pdch *pdch);
+int l1gprs_pdch_disable(struct l1gprs_pdch *pdch);
+
+int l1gprs_handle_pdtch_ind(struct l1gprs_pdch *pdch,
+ const struct l1gprs_prim_data_ind *ind);
+int l1gprs_handle_ptcch_ind(struct l1gprs_pdch *pdch,
+ const struct l1gprs_prim_data_ind *ind);
diff --git a/src/host/trxcon/include/osmocom/bb/l1gprs/logging.h
b/src/host/trxcon/include/osmocom/bb/l1gprs/logging.h
new file mode 100644
index 0000000..422cc03
--- /dev/null
+++ b/src/host/trxcon/include/osmocom/bb/l1gprs/logging.h
@@ -0,0 +1,13 @@
+#pragma once
+
+extern int l1gprs_log_cat_grr;
+
+void l1gprs_logging_init(int logc);
+
+#define LOGP_GRR(grr, level, fmt, args...) \
+ LOGP(l1gprs_log_cat_grr, level, "%s" fmt, \
+ (grr)->log_prefix, ## args)
+
+#define LOGP_PDCH(pdch, level, fmt, args...) \
+ LOGP_GRR((pdch->grr), level, "(PDCH-%u) " fmt, \
+ (pdch->tn), ## args)
diff --git a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
index 4b743ca..1efa00b 100644
--- a/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
+++ b/src/host/trxcon/include/osmocom/bb/l1sched/l1sched.h
@@ -350,6 +350,8 @@
struct llist_head tx_prims;
/*! Backpointer to the scheduler */
struct l1sched_state *sched;
+ /*! Some private data for API user */
+ void *priv;
};
/* Represents one TX primitive in the queue of l1sched_ts */
diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/logging.h
b/src/host/trxcon/include/osmocom/bb/trxcon/logging.h
index f8521a0..925f602 100644
--- a/src/host/trxcon/include/osmocom/bb/trxcon/logging.h
+++ b/src/host/trxcon/include/osmocom/bb/trxcon/logging.h
@@ -10,6 +10,7 @@
DTRXD,
DSCH,
DSCHD,
+ DGRR,
};
int trxcon_logging_init(void *tall_ctx, const char *category_mask);
diff --git a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
index 9148771..5af6cf9 100644
--- a/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
+++ b/src/host/trxcon/include/osmocom/bb/trxcon/trxcon.h
@@ -4,6 +4,7 @@
struct osmo_fsm_inst;
struct l1sched_state;
+struct l1gprs_grr_inst;
struct msgb;
struct trxcon_inst {
@@ -18,6 +19,9 @@
/* The L1 scheduler */
struct l1sched_state *sched;
+ /* GPRS RR state (RLC/MAC layer) */
+ struct l1gprs_grr_inst *grr;
+
/* PHY interface (e.g. TRXC/TRXD) */
void *phyif;
/* L2 interface (e.g. L1CTL) */
@@ -40,6 +44,7 @@
TRXCON_LOGC_L1D, /* L1CTL data */
TRXCON_LOGC_SCHC, /* l1sched control */
TRXCON_LOGC_SCHD, /* l1sched data */
+ TRXCON_LOGC_GRR, /* l1gprs logging */
};
void trxcon_set_log_cfg(const int *logc, unsigned int logc_num);
diff --git a/src/host/trxcon/src/Makefile.am b/src/host/trxcon/src/Makefile.am
index a286f2a..44546d1 100644
--- a/src/host/trxcon/src/Makefile.am
+++ b/src/host/trxcon/src/Makefile.am
@@ -8,6 +8,7 @@
$(LIBOSMOCORE_CFLAGS) \
$(LIBOSMOCODING_CFLAGS) \
$(LIBOSMOGSM_CFLAGS) \
+ $(LIBOSMOGPRSRLCMAC_CFLAGS) \
$(NULL)
@@ -29,6 +30,19 @@
$(NULL)
+noinst_LTLIBRARIES += libl1gprs.la
+
+libl1gprs_la_SOURCES = \
+ gprs.c \
+ $(NULL)
+
+libl1gprs_la_LIBADD = \
+ $(LIBOSMOCORE_LIBS) \
+ $(LIBOSMOGSM_LIBS) \
+ $(LIBOSMOGPRSRLCMAC_LIBS) \
+ $(NULL)
+
+
noinst_LTLIBRARIES += libtrxcon.la
libtrxcon_la_SOURCES = \
@@ -51,6 +65,7 @@
trxcon_LDADD = \
libtrxcon.la \
libl1sched.la \
+ libl1gprs.la \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOCODING_LIBS) \
$(LIBOSMOGSM_LIBS) \
diff --git a/src/host/trxcon/src/gprs.c b/src/host/trxcon/src/gprs.c
new file mode 100644
index 0000000..a550946
--- /dev/null
+++ b/src/host/trxcon/src/gprs.c
@@ -0,0 +1,177 @@
+/*
+ * OsmocomBB <-> SDR connection bridge
+ *
+ * (C) 2022 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de>
+ * Author: Vadim Yanitskiy <vyanitskiy(a)sysmocom.de>
+ *
+ * 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.
+ *
+ */
+
+#include <errno.h>
+#include <stdint.h>
+
+#include <osmocom/core/logging.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/bitvec.h>
+#include <osmocom/core/utils.h>
+
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gprs/rlcmac/gprs_rlcmac.h>
+#include <osmocom/gprs/gprs_rlc.h>
+
+#include <osmocom/bb/l1gprs/l1gprs.h>
+#include <osmocom/bb/l1gprs/logging.h>
+
+int l1gprs_log_cat_grr = DLGLOBAL;
+
+/* TODO: move to libosmo-gprs-rlcmac */
+enum gprs_rlcmac_block_type {
+ GPRS_RLCMAC_DATA_BLOCK = 0x00,
+ GPRS_RLCMAC_CONTROL_BLOCK = 0x01,
+ GPRS_RLCMAC_CONTROL_BLOCK_OPT = 0x02,
+ GPRS_RLCMAC_RESERVED = 0x03,
+};
+
+void l1gprs_logging_init(int logc)
+{
+ l1gprs_log_cat_grr = logc;
+}
+
+struct l1gprs_grr_inst *l1gprs_grr_inst_alloc(void *ctx, const char *log_prefix, void
*priv)
+{
+ struct l1gprs_grr_inst *grr;
+
+ grr = talloc_zero(ctx, struct l1gprs_grr_inst);
+ if (grr == NULL)
+ return NULL;
+
+ for (unsigned int tn = 0; tn < ARRAY_SIZE(grr->pdch); tn++) {
+ struct l1gprs_pdch *pdch = &grr->pdch[tn];
+
+ pdch->tn = tn;
+ pdch->grr = grr;
+ }
+
+ if (log_prefix == NULL)
+ grr->log_prefix = talloc_asprintf(grr, "l1gprs[0x%p]: ", grr);
+ else
+ grr->log_prefix = talloc_strdup(grr, log_prefix);
+ grr->priv = priv;
+
+ return grr;
+}
+
+void l1gprs_grr_inst_free(struct l1gprs_grr_inst *grr)
+{
+ if (grr == NULL)
+ return;
+
+ for (unsigned int tn = 0; tn < ARRAY_SIZE(grr->pdch); tn++)
+ l1gprs_pdch_disable(&grr->pdch[tn]);
+ talloc_free(grr);
+}
+
+int l1gprs_pdch_enable(struct l1gprs_pdch *pdch)
+{
+ if (pdch->enabled)
+ return -EALREADY;
+
+ pdch->enabled = true;
+ return 0;
+}
+
+int l1gprs_pdch_disable(struct l1gprs_pdch *pdch)
+{
+ if (!pdch->enabled)
+ return -EALREADY;
+
+ pdch->enabled = false;
+ return 0;
+}
+
+static void handle_pdtch_gprs_block(struct l1gprs_pdch *pdch,
+ const enum osmo_gprs_cs cs,
+ const uint8_t *data, size_t data_len)
+{
+ const uint8_t pt = data[0] >> 6;
+ RlcMacDownlink_t *ctrl_block;
+ struct bitvec *bv;
+
+ ctrl_block = talloc_zero(pdch->grr, RlcMacDownlink_t);
+ OSMO_ASSERT(ctrl_block != NULL);
+
+ bv = bitvec_alloc(data_len, pdch->grr);
+ OSMO_ASSERT(bv != NULL);
+ bitvec_unpack(bv, data);
+
+ switch (pt) {
+ case GPRS_RLCMAC_CONTROL_BLOCK:
+ osmo_gprs_rlcmac_decode_downlink(bv, ctrl_block);
+ break;
+ case GPRS_RLCMAC_DATA_BLOCK: /* TODO */
+ default:
+ break;
+ }
+
+ talloc_free(ctrl_block);
+ talloc_free(bv);
+}
+
+int l1gprs_handle_pdtch_ind(struct l1gprs_pdch *pdch,
+ const struct l1gprs_prim_data_ind *ind)
+{
+ const enum osmo_gprs_cs cs = osmo_gprs_dl_cs_by_block_bytes(ind->data_len);
+
+ if (!pdch->enabled) {
+ LOGP_PDCH(pdch, LOGL_ERROR, "Rx PDTCH/D block for disabled PDCH\n");
+ return -ENODEV;
+ }
+
+ switch (cs) {
+ case OSMO_GPRS_CS1:
+ case OSMO_GPRS_CS2:
+ case OSMO_GPRS_CS3:
+ case OSMO_GPRS_CS4:
+ handle_pdtch_gprs_block(pdch, cs, &ind->data[0], ind->data_len);
+ return 0;
+ case OSMO_GPRS_CS_NONE:
+ LOGP_PDCH(pdch, LOGL_ERROR,
+ "Failed to determine Coding Scheme (len=%zu)\n", ind->data_len);
+ return -EINVAL;
+ default:
+ LOGP_PDCH(pdch, LOGL_NOTICE, "Coding Scheme %d is not supported\n", cs);
+ return -ENOTSUP;
+ }
+}
+
+int l1gprs_handle_ptcch_ind(struct l1gprs_pdch *pdch,
+ const struct l1gprs_prim_data_ind *ind)
+{
+ if (!pdch->enabled) {
+ LOGP_PDCH(pdch, LOGL_ERROR, "Rx PTCCH/D block for disabled PDCH\n");
+ return -ENODEV;
+ }
+
+ if (ind->data_len != GSM_MACBLOCK_LEN) {
+ LOGP_PDCH(pdch, LOGL_ERROR,
+ "Rx PTCCH/D block with unexpected length=%zu (expected %u)\n",
+ ind->data_len, GSM_MACBLOCK_LEN);
+ return -EINVAL;
+ }
+
+ LOGP_PDCH(pdch, LOGL_INFO, "Rx PTCCH/D block: %s\n",
+ osmo_hexdump(ind->data, ind->data_len));
+
+ return 0;
+}
diff --git a/src/host/trxcon/src/logging.c b/src/host/trxcon/src/logging.c
index 2222577..763a78d 100644
--- a/src/host/trxcon/src/logging.c
+++ b/src/host/trxcon/src/logging.c
@@ -67,6 +67,12 @@
.color = "\033[1;36m",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
+ [DGRR] = {
+ .name = "DGRR",
+ .description = "GPRS RR",
+ .color = "\033[1;36m",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
};
static const struct log_info trxcon_log_info = {
@@ -80,6 +86,7 @@
[TRXCON_LOGC_L1D] = DL1D,
[TRXCON_LOGC_SCHC] = DSCH,
[TRXCON_LOGC_SCHD] = DSCHD,
+ [TRXCON_LOGC_GRR] = DGRR,
};
int trxcon_logging_init(void *tall_ctx, const char *category_mask)
diff --git a/src/host/trxcon/src/trxcon_fsm.c b/src/host/trxcon/src/trxcon_fsm.c
index 10663b1..575d75c 100644
--- a/src/host/trxcon/src/trxcon_fsm.c
+++ b/src/host/trxcon/src/trxcon_fsm.c
@@ -36,6 +36,7 @@
#include <osmocom/bb/trxcon/l1ctl.h>
#include <osmocom/bb/l1sched/l1sched.h>
#include <osmocom/bb/l1sched/logging.h>
+#include <osmocom/bb/l1gprs/l1gprs.h>
#define S(x) (1 << (x))
@@ -537,11 +538,18 @@
case TRXCON_EV_RX_DATA_IND:
{
const struct trxcon_param_rx_data_ind *ind = data;
+ const unsigned int tn = ind->chan_nr & 0x07;
- if (ind->link_id == 0x00)
- LOGPFSML(fi, LOGL_NOTICE, "Rx PDTCH/D message\n");
+ const struct l1gprs_prim_data_ind grr_ind = {
+ .frame_nr = ind->frame_nr,
+ .data_len = ind->data_len,
+ .data = ind->data,
+ };
+
+ if (ind->link_id == L1SCHED_CH_LID_PTCCH)
+ l1gprs_handle_ptcch_ind(&trxcon->grr->pdch[tn], &grr_ind);
else
- LOGPFSML(fi, LOGL_NOTICE, "Rx PTCCH/D message\n");
+ l1gprs_handle_pdtch_ind(&trxcon->grr->pdch[tn], &grr_ind);
break;
}
case TRXCON_EV_DCH_EST_REQ:
@@ -567,6 +575,10 @@
/* Shutdown the scheduler */
if (trxcon->sched != NULL)
l1sched_free(trxcon->sched);
+ /* Shutdown GPRS RR layer */
+ if (trxcon->grr == NULL)
+ l1gprs_grr_inst_free(trxcon->grr);
+
/* Close active connections */
if (trxcon->l2if != NULL)
trxcon_l1ctl_close(trxcon);
diff --git a/src/host/trxcon/src/trxcon_inst.c b/src/host/trxcon/src/trxcon_inst.c
index 7d3813e..6db3a1b 100644
--- a/src/host/trxcon/src/trxcon_inst.c
+++ b/src/host/trxcon/src/trxcon_inst.c
@@ -27,6 +27,8 @@
#include <osmocom/bb/trxcon/trxcon_fsm.h>
#include <osmocom/bb/l1sched/l1sched.h>
#include <osmocom/bb/l1sched/logging.h>
+#include <osmocom/bb/l1gprs/l1gprs.h>
+#include <osmocom/bb/l1gprs/logging.h>
extern int g_logc_l1c;
extern int g_logc_l1d;
@@ -53,6 +55,9 @@
case TRXCON_LOGC_SCHD:
schd = logc[i];
break;
+ case TRXCON_LOGC_GRR:
+ l1gprs_logging_init(logc[i]);
+ break;
}
}
@@ -91,6 +96,13 @@
return NULL;
}
+ /* Init GPRS RR layer */
+ trxcon->grr = l1gprs_grr_inst_alloc(trxcon, trxcon->log_prefix, trxcon);
+ if (trxcon->grr == NULL) {
+ trxcon_inst_free(trxcon);
+ return NULL;
+ }
+
return trxcon;
}
--
To view, visit
https://gerrit.osmocom.org/c/osmocom-bb/+/30743
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: I9567d64f9d00262e36147e8d7e541e5e246bda5f
Gerrit-Change-Number: 30743
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-MessageType: newchange