summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2023-01-25 20:41:54 +0100
committerpespin <pespin@sysmocom.de>2023-01-30 19:57:36 +0000
commit60716bcfe6dac4a77ff367a59b314b1bd4e56ad0 (patch)
tree79c4b3095a0e968ff1c9d041ec781ef7a55d067d /src
parent53996bb3d84352550f8c56ee9fe4ef396644f518 (diff)
modem: Initial integration of libosmo-gprs-rlcmac
This commit places code to forward unitdata LLC<->RLCMAC. Depends: libosmo-gprs.git Change-Id I1870fa6a264612c5a669bfb832e6e8c0a892cb74 Related: OS#5500 Change-Id: I0e628d9ddaa5ad6a205f07746d4176d1b8df7eb0
Diffstat (limited to 'src')
-rw-r--r--src/host/layer23/include/osmocom/bb/common/logging.h1
-rw-r--r--src/host/layer23/include/osmocom/bb/modem/Makefile.am1
-rw-r--r--src/host/layer23/include/osmocom/bb/modem/rlcmac.h8
-rw-r--r--src/host/layer23/src/common/logging.c10
-rw-r--r--src/host/layer23/src/modem/Makefile.am1
-rw-r--r--src/host/layer23/src/modem/app_modem.c6
-rw-r--r--src/host/layer23/src/modem/llc.c15
-rw-r--r--src/host/layer23/src/modem/rlcmac.c138
8 files changed, 177 insertions, 3 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/logging.h b/src/host/layer23/include/osmocom/bb/common/logging.h
index 912b7d45..818b1495 100644
--- a/src/host/layer23/include/osmocom/bb/common/logging.h
+++ b/src/host/layer23/include/osmocom/bb/common/logging.h
@@ -27,6 +27,7 @@ enum {
DLUA,
DGAPK,
DTUN,
+ DRLCMAC,
DLLC,
DSNDCP,
};
diff --git a/src/host/layer23/include/osmocom/bb/modem/Makefile.am b/src/host/layer23/include/osmocom/bb/modem/Makefile.am
index 4a91c395..4acb21b0 100644
--- a/src/host/layer23/include/osmocom/bb/modem/Makefile.am
+++ b/src/host/layer23/include/osmocom/bb/modem/Makefile.am
@@ -1,6 +1,7 @@
noinst_HEADERS = \
modem.h \
llc.h \
+ rlcmac.h \
sndcp.h \
vty.h \
$(NULL)
diff --git a/src/host/layer23/include/osmocom/bb/modem/rlcmac.h b/src/host/layer23/include/osmocom/bb/modem/rlcmac.h
new file mode 100644
index 00000000..d1b054f8
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/modem/rlcmac.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include <stdbool.h>
+
+struct osmocom_ms;
+
+int modem_rlcmac_init(struct osmocom_ms *ms);
+
diff --git a/src/host/layer23/src/common/logging.c b/src/host/layer23/src/common/logging.c
index 66dc4161..a31eb229 100644
--- a/src/host/layer23/src/common/logging.c
+++ b/src/host/layer23/src/common/logging.c
@@ -153,16 +153,22 @@ static const struct log_info_cat default_categories[] = {
.color = "\033[0;37m",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
+ [DRLCMAC] = {
+ .name = "DRLCMAC",
+ .description = "Radio Link Control / Medium Access Control (RLC/MAC)",
+ .color = "\033[0;38m",
+ .enabled = 1, .loglevel = LOGL_NOTICE,
+ },
[DLLC] = {
.name = "DLLC",
.description = "GPRS Logical Link Control Protocol (LLC)",
- .color = "\033[0;38m",
+ .color = "\033[0;39m",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
[DSNDCP] = {
.name = "DSNDCP",
.description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
- .color = "\033[0;39m",
+ .color = "\033[0;40m",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
};
diff --git a/src/host/layer23/src/modem/Makefile.am b/src/host/layer23/src/modem/Makefile.am
index e13ea2d0..7ce71dc9 100644
--- a/src/host/layer23/src/modem/Makefile.am
+++ b/src/host/layer23/src/modem/Makefile.am
@@ -19,6 +19,7 @@ modem_SOURCES = \
$(top_srcdir)/src/common/main.c \
app_modem.c \
llc.c \
+ rlcmac.c \
sndcp.c \
vty.c \
$(NULL)
diff --git a/src/host/layer23/src/modem/app_modem.c b/src/host/layer23/src/modem/app_modem.c
index 1be2cbcf..14fdf2f1 100644
--- a/src/host/layer23/src/modem/app_modem.c
+++ b/src/host/layer23/src/modem/app_modem.c
@@ -48,6 +48,7 @@
#include <osmocom/bb/common/l1l2_interface.h>
#include <osmocom/bb/common/sysinfo.h>
#include <osmocom/bb/common/apn.h>
+#include <osmocom/bb/modem/rlcmac.h>
#include <osmocom/bb/modem/llc.h>
#include <osmocom/bb/modem/sndcp.h>
#include <osmocom/bb/modem/vty.h>
@@ -552,6 +553,11 @@ int l23_app_init(void)
app_data.ms = osmocom_ms_alloc(l23_ctx, "1");
OSMO_ASSERT(app_data.ms);
+ if ((rc = modem_rlcmac_init(app_data.ms))) {
+ LOGP(DRLCMAC, LOGL_FATAL, "Failed initializing RLC/MAC layer\n");
+ return rc;
+ }
+
if ((rc = modem_llc_init(app_data.ms, NULL))) {
LOGP(DLLC, LOGL_FATAL, "Failed initializing LLC layer\n");
return rc;
diff --git a/src/host/layer23/src/modem/llc.c b/src/host/layer23/src/modem/llc.c
index 196c2409..4bb0684b 100644
--- a/src/host/layer23/src/modem/llc.c
+++ b/src/host/layer23/src/modem/llc.c
@@ -33,6 +33,7 @@
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gprs/llc/llc_prim.h>
#include <osmocom/gprs/llc/llc.h>
+#include <osmocom/gprs/rlcmac/rlcmac_prim.h>
#include <osmocom/gprs/sndcp/sndcp_prim.h>
#include <osmocom/bb/common/logging.h>
@@ -141,10 +142,22 @@ int modem_llc_prim_down_cb(struct osmo_gprs_llc_prim *llc_prim, void *user_data)
const char *pdu_name = osmo_gprs_llc_prim_name(llc_prim);
int rc = 0;
+ osmo_static_assert(sizeof(struct osmo_gprs_llc_grr_prim) == sizeof(struct osmo_gprs_rlcmac_grr_prim),
+ _grr_prim_size);
+
switch (llc_prim->oph.sap) {
case OSMO_GPRS_LLC_SAP_GRR:
- LOGP(DLLC, LOGL_DEBUG, "%s(): Rx %s l3=[%s]\n", __func__, pdu_name,
+ LOGP(DLLC, LOGL_DEBUG, "%s(): Rx %s ll=[%s]\n", __func__, pdu_name,
osmo_hexdump(llc_prim->grr.ll_pdu, llc_prim->grr.ll_pdu_len));
+ /* Forward it to lower layers, pass ownership over to RLCMAC: */
+ /* Optimization: LLC-GRR-UNITDATA-IND is 1-to-1 ABI compatible with
+ RLCMAC-GRR-UNITDATA-IND, we just need to adapt the header.
+ See osmo_static_assert(_grr_prim_size) above.
+ */
+ llc_prim->oph.sap = OSMO_GPRS_RLCMAC_SAP_GRR;
+ llc_prim->oph.primitive = OSMO_GPRS_RLCMAC_GRR_UNITDATA;
+ osmo_gprs_rlcmac_prim_upper_down((struct osmo_gprs_rlcmac_prim *)llc_prim);
+ rc = 1; /* Tell RLCMAC that we take ownership of the prim. */
break;
default:
LOGP(DLLC, LOGL_DEBUG, "%s(): Unexpected Rx %s\n", __func__, pdu_name);
diff --git a/src/host/layer23/src/modem/rlcmac.c b/src/host/layer23/src/modem/rlcmac.c
new file mode 100644
index 00000000..83dcd6cc
--- /dev/null
+++ b/src/host/layer23/src/modem/rlcmac.c
@@ -0,0 +1,138 @@
+/* GPRS RLC/MAC protocol implementation as per 3GPP TS 44.060 */
+/* (C) 2023 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * All Rights Reserved
+ * Author: Pau Espin Pedrol <pespin@sysmocom.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/lienses/>.
+ *
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/timer.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/rate_ctr.h>
+#include <osmocom/crypt/kdf.h>
+#include <osmocom/gprs/gprs_bssgp.h>
+#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gprs/rlcmac/rlcmac_prim.h>
+#include <osmocom/gprs/rlcmac/rlcmac.h>
+#include <osmocom/gprs/llc/llc_prim.h>
+
+#include <osmocom/bb/common/logging.h>
+#include <osmocom/bb/common/apn.h>
+#include <osmocom/bb/common/ms.h>
+#include <osmocom/bb/modem/rlcmac.h>
+
+static int modem_rlcmac_handle_grr(struct osmo_gprs_rlcmac_prim *rlcmac_prim)
+{
+ int rc;
+
+ osmo_static_assert(sizeof(struct osmo_gprs_rlcmac_grr_prim) == sizeof(struct osmo_gprs_llc_grr_prim),
+ _grr_prim_size);
+
+ switch (rlcmac_prim->oph.primitive) {
+ case OSMO_GPRS_RLCMAC_GRR_UNITDATA:
+ /* Forward it to upper layers, pass ownership over to LLC: */
+ /* Optimization: RLCMAC-GRR-UNITDATA-IND is 1-to-1 ABI compatible with
+ LLC-GRR-UNITDATA-IND, we just need to adapt the header.
+ See osmo_static_assert(_grr_prim_size) above.
+ */
+ rlcmac_prim->oph.sap = OSMO_GPRS_LLC_SAP_GRR;
+ rlcmac_prim->oph.primitive = OSMO_GPRS_LLC_GRR_UNITDATA;
+ osmo_gprs_llc_prim_lower_up((struct osmo_gprs_llc_prim *)rlcmac_prim);
+ rc = 1; /* Tell RLCMAC that we take ownership of the prim. */
+ break;
+ case OSMO_GPRS_RLCMAC_GRR_DATA:
+ default:
+ LOGP(DRLCMAC, LOGL_NOTICE, "%s(): Unexpected Rx RLCMAC GRR prim %u\n",
+ __func__, rlcmac_prim->oph.primitive);
+ rc = -EINVAL;
+ break;
+ }
+ return rc;
+}
+
+static int modem_rlcmac_handle_gmmrr(struct osmo_gprs_rlcmac_prim *rlcmac_prim)
+{
+ int rc;
+ switch (rlcmac_prim->oph.primitive) {
+ case OSMO_GPRS_RLCMAC_GMMRR_PAGE:
+ LOGP(DRLCMAC, LOGL_ERROR, "%s(): TODO: implement answering to paging indication TLLI=0x%08x\n",
+ __func__, rlcmac_prim->gmmrr.page_ind.tlli);
+ rc = 0;
+ break;
+ default:
+ LOGP(DRLCMAC, LOGL_NOTICE, "%s(): Unexpected Rx RLCMAC GMMRR prim %u\n",
+ __func__, rlcmac_prim->oph.primitive);
+ rc = -EINVAL;
+ }
+ return rc;
+}
+
+static int modem_rlcmac_prim_up_cb(struct osmo_gprs_rlcmac_prim *rlcmac_prim, void *user_data)
+{
+ const char *pdu_name = osmo_gprs_rlcmac_prim_name(rlcmac_prim);
+ int rc = 0;
+
+ switch (rlcmac_prim->oph.sap) {
+ case OSMO_GPRS_RLCMAC_SAP_GRR:
+ LOGP(DRLCMAC, LOGL_DEBUG, "%s(): Rx %s TLLI=0x%08x ll=[%s]\n",
+ __func__, pdu_name, rlcmac_prim->grr.tlli,
+ osmo_hexdump(rlcmac_prim->grr.ll_pdu, rlcmac_prim->grr.ll_pdu_len));
+ rc = modem_rlcmac_handle_grr(rlcmac_prim);
+ break;
+ case OSMO_GPRS_RLCMAC_SAP_GMMRR:
+ LOGP(DRLCMAC, LOGL_DEBUG, "%s(): Rx %s\n",
+ __func__, pdu_name);
+ rc = modem_rlcmac_handle_gmmrr(rlcmac_prim);
+ break;
+ default:
+ LOGP(DRLCMAC, LOGL_NOTICE, "%s(): Unexpected Rx %s\n", __func__, pdu_name);
+ OSMO_ASSERT(0);
+ }
+ return rc;
+}
+
+static int modem_rlcmac_prim_down_cb(struct osmo_gprs_rlcmac_prim *rlcmac_prim, void *user_data)
+{
+ const char *pdu_name = osmo_gprs_rlcmac_prim_name(rlcmac_prim);
+ int rc = 0;
+
+ switch (rlcmac_prim->oph.sap) {
+ default:
+ LOGP(DRLCMAC, LOGL_DEBUG, "%s(): Unexpected Rx %s\n", __func__, pdu_name);
+ OSMO_ASSERT(0);
+ }
+ return rc;
+}
+
+int modem_rlcmac_init(struct osmocom_ms *ms)
+{
+ int rc;
+ rc = osmo_gprs_rlcmac_init(OSMO_GPRS_RLCMAC_LOCATION_MS);
+ if (rc != 0)
+ return rc;
+
+ osmo_gprs_rlcmac_set_log_cat(OSMO_GPRS_RLCMAC_LOGC_RLCMAC, DRLCMAC);
+
+ osmo_gprs_rlcmac_prim_set_up_cb(modem_rlcmac_prim_up_cb, ms);
+ osmo_gprs_rlcmac_prim_set_down_cb(modem_rlcmac_prim_down_cb, ms);
+ return rc;
+}