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 <[email protected]>
+ * Author: Vadim Yanitskiy <[email protected]>
+ *
+ * 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 <[email protected]>
Gerrit-MessageType: newchange

Reply via email to