pespin submitted this change.

View Change


Approvals: fixeria: Looks good to me, approved pespin: Verified
modem: initial SM layer support through libosmo-gprs-sm

Depends: libosmo-gprs.git Change-Id I9b4a9a6364f7799540475e7e1d10ab2310768281
Related: OS#5501
Change-Id: I9476d93954c7dc348e6f97ca89eaa651f802f9a0
---
M src/host/layer23/configure.ac
M src/host/layer23/include/osmocom/bb/common/logging.h
M src/host/layer23/include/osmocom/bb/modem/Makefile.am
A src/host/layer23/include/osmocom/bb/modem/sm.h
M src/host/layer23/src/common/logging.c
M src/host/layer23/src/modem/Makefile.am
M src/host/layer23/src/modem/app_modem.c
A src/host/layer23/src/modem/sm.c
M src/host/layer23/src/modem/vty.c
9 files changed, 228 insertions(+), 0 deletions(-)

diff --git a/src/host/layer23/configure.ac b/src/host/layer23/configure.ac
index 1434fbf..b4eb860 100644
--- a/src/host/layer23/configure.ac
+++ b/src/host/layer23/configure.ac
@@ -50,6 +50,7 @@
PKG_CHECK_MODULES(LIBOSMOGPRSLLC, libosmo-gprs-llc)
PKG_CHECK_MODULES(LIBOSMOGPRSSNDCP, libosmo-gprs-sndcp)
PKG_CHECK_MODULES(LIBOSMOGPRSGMM, libosmo-gprs-gmm)
+PKG_CHECK_MODULES(LIBOSMOGPRSSM, libosmo-gprs-sm)
AC_CHECK_LIB(gps, gps_waiting, LIBGPS_CFLAGS=" -D_HAVE_GPSD" LIBGPS_LIBS=" -lgps ",,)
AC_SUBST([LIBGPS_CFLAGS])
AC_SUBST([LIBGPS_LIBS])
diff --git a/src/host/layer23/include/osmocom/bb/common/logging.h b/src/host/layer23/include/osmocom/bb/common/logging.h
index fc0861e..fa76c59 100644
--- a/src/host/layer23/include/osmocom/bb/common/logging.h
+++ b/src/host/layer23/include/osmocom/bb/common/logging.h
@@ -31,6 +31,7 @@
DLLC,
DSNDCP,
DGMM,
+ DSM
};

extern const struct log_info log_info;
diff --git a/src/host/layer23/include/osmocom/bb/modem/Makefile.am b/src/host/layer23/include/osmocom/bb/modem/Makefile.am
index 6dfc98e..2f69d19 100644
--- a/src/host/layer23/include/osmocom/bb/modem/Makefile.am
+++ b/src/host/layer23/include/osmocom/bb/modem/Makefile.am
@@ -4,6 +4,7 @@
grr.h \
llc.h \
rlcmac.h \
+ sm.h \
sndcp.h \
vty.h \
$(NULL)
diff --git a/src/host/layer23/include/osmocom/bb/modem/sm.h b/src/host/layer23/include/osmocom/bb/modem/sm.h
new file mode 100644
index 0000000..51000cf
--- /dev/null
+++ b/src/host/layer23/include/osmocom/bb/modem/sm.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include <stdbool.h>
+
+struct osmocom_ms;
+
+int modem_sm_init(struct osmocom_ms *ms);
diff --git a/src/host/layer23/src/common/logging.c b/src/host/layer23/src/common/logging.c
index e3a5beb..d1b5b92 100644
--- a/src/host/layer23/src/common/logging.c
+++ b/src/host/layer23/src/common/logging.c
@@ -177,6 +177,12 @@
.color = "\033[0;32m",
.enabled = 1, .loglevel = LOGL_NOTICE,
},
+ [DSM] = {
+ .name = "DSM",
+ .description = "GPRS Session Management (SM)",
+ .color = "\033[0;31m",
+ .enabled = 1, .loglevel = LOGL_NOTICE,
+ },
};

const struct log_info log_info = {
diff --git a/src/host/layer23/src/modem/Makefile.am b/src/host/layer23/src/modem/Makefile.am
index 086c2f3..935722b 100644
--- a/src/host/layer23/src/modem/Makefile.am
+++ b/src/host/layer23/src/modem/Makefile.am
@@ -12,6 +12,7 @@
$(LIBOSMOGPRSLLC_CFLAGS) \
$(LIBOSMOGPRSSNDCP_CFLAGS) \
$(LIBOSMOGPRSGMM_CFLAGS) \
+ $(LIBOSMOGPRSSM_CFLAGS) \
$(NULL)

bin_PROGRAMS = modem
@@ -23,6 +24,7 @@
grr.c \
llc.c \
rlcmac.c \
+ sm.c \
sndcp.c \
vty.c \
$(NULL)
@@ -35,4 +37,5 @@
$(LIBOSMOGPRSLLC_LIBS) \
$(LIBOSMOGPRSSNDCP_LIBS) \
$(LIBOSMOGPRSGMM_LIBS) \
+ $(LIBOSMOGPRSSM_LIBS) \
$(NULL)
diff --git a/src/host/layer23/src/modem/app_modem.c b/src/host/layer23/src/modem/app_modem.c
index cecf4e6..644c630 100644
--- a/src/host/layer23/src/modem/app_modem.c
+++ b/src/host/layer23/src/modem/app_modem.c
@@ -51,6 +51,7 @@
#include <osmocom/bb/modem/llc.h>
#include <osmocom/bb/modem/sndcp.h>
#include <osmocom/bb/modem/gmm.h>
+#include <osmocom/bb/modem/sm.h>
#include <osmocom/bb/modem/vty.h>
#include <osmocom/bb/modem/grr.h>

@@ -180,6 +181,11 @@
return rc;
}

+ if ((rc = modem_sm_init(app_data.ms))) {
+ LOGP(DSM, LOGL_FATAL, "Failed initializing SM layer\n");
+ return rc;
+ }
+
osmo_signal_register_handler(SS_L1CTL, &signal_cb, NULL);
lapdm_channel_set_l3(&app_data.ms->lapdm_channel, &modem_grr_rslms_cb, app_data.ms);
return 0;
diff --git a/src/host/layer23/src/modem/sm.c b/src/host/layer23/src/modem/sm.c
new file mode 100644
index 0000000..5dc80e0
--- /dev/null
+++ b/src/host/layer23/src/modem/sm.c
@@ -0,0 +1,120 @@
+/* GPRS SM interfaces as per 3GPP TS 24.008, TS 24.007 */
+/* (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 <stdbool.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/prim.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/tun.h>
+#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
+
+#include <osmocom/gprs/gmm/gmm.h>
+#include <osmocom/gprs/gmm/gmm_prim.h>
+#include <osmocom/gprs/sm/sm_prim.h>
+#include <osmocom/gprs/sm/sm.h>
+#include <osmocom/gprs/rlcmac/rlcmac_prim.h>
+
+#include <osmocom/bb/common/settings.h>
+#include <osmocom/bb/common/logging.h>
+#include <osmocom/bb/common/apn.h>
+#include <osmocom/bb/common/ms.h>
+#include <osmocom/bb/modem/sm.h>
+
+static int modem_sm_prim_up_cb(struct osmo_gprs_sm_prim *sm_prim, void *user_data)
+{
+ const char *pdu_name = osmo_gprs_sm_prim_name(sm_prim);
+ int rc = 0;
+
+ switch (sm_prim->oph.sap) {
+ case OSMO_GPRS_SM_SAP_SMREG:
+ switch (OSMO_PRIM_HDR(&sm_prim->oph)) {
+ case OSMO_PRIM(OSMO_GPRS_SM_SMREG_PDP_ACTIVATE, PRIM_OP_CONFIRM):
+ if (sm_prim->smreg.pdp_act_cnf.accepted)
+ LOGP(DSM, LOGL_INFO, "%s(): Rx %s (TODO: set IP address in tun device)\n", __func__, pdu_name);
+ else
+ LOGP(DSM, LOGL_INFO, "%s(): Rx %s: Activate PDP failed! cause '%s'\n", __func__, pdu_name,
+ get_value_string(gsm48_gsm_cause_names, sm_prim->smreg.pdp_act_cnf.rej.cause));
+ break;
+ case OSMO_PRIM(OSMO_GPRS_SM_SMREG_PDP_ACTIVATE, PRIM_OP_INDICATION):
+ case OSMO_PRIM(OSMO_GPRS_SM_SMREG_PDP_DEACTIVATE, PRIM_OP_CONFIRM):
+ case OSMO_PRIM(OSMO_GPRS_SM_SMREG_PDP_DEACTIVATE, PRIM_OP_INDICATION):
+ case OSMO_PRIM(OSMO_GPRS_SM_SMREG_PDP_MODIFY, PRIM_OP_CONFIRM):
+ case OSMO_PRIM(OSMO_GPRS_SM_SMREG_PDP_MODIFY, PRIM_OP_INDICATION):
+ case OSMO_PRIM(OSMO_GPRS_SM_SMREG_PDP_ACTIVATE_SEC, PRIM_OP_CONFIRM):
+ default:
+ LOGP(DSM, LOGL_ERROR, "%s(): Rx %s UNIMPLEMENTED\n", __func__, pdu_name);
+ break;
+ };
+ break;
+ default:
+ LOGP(DSM, LOGL_ERROR, "%s(): Unexpected Rx %s\n", __func__, pdu_name);
+ OSMO_ASSERT(0);
+ }
+
+ return rc;
+}
+
+static int modem_sm_prim_down_cb(struct osmo_gprs_sm_prim *sm_prim, void *user_data)
+{
+ const char *pdu_name = osmo_gprs_sm_prim_name(sm_prim);
+ int rc = 0;
+
+ switch (sm_prim->oph.sap) {
+ default:
+ LOGP(DSM, LOGL_ERROR, "%s(): Unexpected Rx %s\n", __func__, pdu_name);
+ OSMO_ASSERT(0);
+ }
+
+ return rc;
+}
+
+static int modem_sm_prim_gmm_down_cb(struct osmo_gprs_gmm_prim *gmm_prim, void *user_data)
+{
+ int rc;
+
+ rc = osmo_gprs_gmm_prim_upper_down(gmm_prim);
+
+ /* GMM took ownership of the message, tell SM layer to not free it: */
+ rc = 1;
+ return rc;
+}
+
+int modem_sm_init(struct osmocom_ms *ms)
+{
+ int rc;
+ rc = osmo_gprs_sm_init(OSMO_GPRS_SM_LOCATION_MS);
+ if (rc != 0)
+ return rc;
+
+ osmo_gprs_sm_set_log_cat(OSMO_GPRS_SM_LOGC_SM, DSM);
+
+ osmo_gprs_sm_prim_set_up_cb(modem_sm_prim_up_cb, ms);
+ osmo_gprs_sm_prim_set_down_cb(modem_sm_prim_down_cb, ms);
+ osmo_gprs_sm_prim_set_gmm_down_cb(modem_sm_prim_gmm_down_cb, ms);
+
+ return rc;
+}
diff --git a/src/host/layer23/src/modem/vty.c b/src/host/layer23/src/modem/vty.c
index 68a46b8..a23ae73 100644
--- a/src/host/layer23/src/modem/vty.c
+++ b/src/host/layer23/src/modem/vty.c
@@ -26,6 +26,8 @@
#include <osmocom/gprs/llc/llc.h>
#include <osmocom/gprs/llc/llc_prim.h>
#include <osmocom/gprs/gmm/gmm_prim.h>
+#include <osmocom/gprs/sm/sm_prim.h>
+

#include <osmocom/vty/vty.h>
#include <osmocom/vty/command.h>
@@ -62,6 +64,7 @@
#define GRR_CMDG_DESC "GPRS RR specific commands\n"
#define LLC_CMDG_DESC "GPRS LLC specific commands\n"
#define GMM_CMDG_DESC "GPRS GMM specific commands\n"
+#define SM_CMDG_DESC "GPRS SM specific commands\n"

/* testing commands */
DEFUN_HIDDEN(test_grr_tx_chan_req,
@@ -212,6 +215,74 @@
return CMD_SUCCESS;
}

+DEFUN_HIDDEN(test_sm_act_pdp_ctx,
+ test_sm_act_pdp_ctx_cmd,
+ "test MS_NAME sm act-pdp-ctx APN",
+ TEST_CMD_DESC MS_NAME_DESC SM_CMDG_DESC
+ "Enqueue a SM SMREG-ACTIVATE.req for transmission\n"
+ "APN to activate\n")
+{
+ struct osmo_gprs_sm_prim *sm_prim;
+ struct osmocom_ms *ms;
+ struct osmobb_apn *apn;
+
+ uint8_t nsapi = 6;
+ enum osmo_gprs_sm_llc_sapi llc_sapi = OSMO_GPRS_SM_LLC_SAPI_SAPI3;
+ struct osmo_sockaddr pdp_addr_any = {0};
+ uint8_t qos[OSMO_GPRS_SM_QOS_MAXLEN] = {0};
+ uint8_t pco[OSMO_GPRS_SM_QOS_MAXLEN] = {0};
+ uint32_t ptmsi = 0x00000000;
+ char *imsi = "1234567890";
+ char *imei = "42342342342342";
+ char *imeisv = "4234234234234275";
+ enum osmo_gprs_sm_pdp_addr_ietf_type pdp_addr_ietf_type;
+
+ if ((ms = l23_vty_get_ms(argv[0], vty)) == NULL) {
+ vty_out(vty, "Unable to find MS '%s'%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ apn = ms_find_apn_by_name(ms, argv[1]);
+ if (!apn) {
+ vty_out(vty, "Unable to find APN '%s'%s", argv[1], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (apn->cfg.apn_type_mask & APN_TYPE_IPv4v6) {
+ pdp_addr_ietf_type = OSMO_GPRS_SM_PDP_ADDR_IETF_IPV4V6;
+ } else if (apn->cfg.apn_type_mask & APN_TYPE_IPv4) {
+ pdp_addr_ietf_type = OSMO_GPRS_SM_PDP_ADDR_IETF_IPV4;
+ } else if (apn->cfg.apn_type_mask & APN_TYPE_IPv6) {
+ pdp_addr_ietf_type = OSMO_GPRS_SM_PDP_ADDR_IETF_IPV6;
+ } else {
+ vty_out(vty, "APN '%s' has no PDP address type set%s", argv[1], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ sm_prim = osmo_gprs_sm_prim_alloc_smreg_pdp_act_req();
+ sm_prim->smreg.pdp_act_req.nsapi = nsapi;
+ sm_prim->smreg.pdp_act_req.llc_sapi = llc_sapi;
+ sm_prim->smreg.pdp_act_req.pdp_addr_ietf_type = pdp_addr_ietf_type;
+ sm_prim->smreg.pdp_act_req.pdp_addr_v4 = pdp_addr_any;
+ sm_prim->smreg.pdp_act_req.pdp_addr_v6 = pdp_addr_any;
+ memcpy(sm_prim->smreg.pdp_act_req.qos, qos, sizeof(qos));
+ sm_prim->smreg.pdp_act_req.qos_len = 1;
+ memcpy(sm_prim->smreg.pdp_act_req.pco, pco, sizeof(pco));
+ sm_prim->smreg.pdp_act_req.pco_len = 1;
+ OSMO_STRLCPY_ARRAY(sm_prim->smreg.pdp_act_req.apn, apn->cfg.name);
+ sm_prim->smreg.pdp_act_req.gmm.ptmsi = ptmsi;
+ OSMO_STRLCPY_ARRAY(sm_prim->smreg.pdp_act_req.gmm.imsi, imsi);
+ OSMO_STRLCPY_ARRAY(sm_prim->smreg.pdp_act_req.gmm.imei, imei);
+ OSMO_STRLCPY_ARRAY(sm_prim->smreg.pdp_act_req.gmm.imeisv, imeisv);
+
+ if (osmo_gprs_sm_prim_upper_down(sm_prim) != 0) {
+ vty_out(vty, "Failed to enqueue a SM PDU%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
/* per APN config */
DEFUN(cfg_ms_apn, cfg_ms_apn_cmd, "apn APN_NAME",
"Configure an APN\n"
@@ -397,6 +468,7 @@
install_element_ve(&test_llc_unitdata_req_gmm_attch_cmd);
install_element_ve(&test_gmm_reg_attach_cmd);
install_element_ve(&test_gmm_reg_detach_cmd);
+ install_element_ve(&test_sm_act_pdp_ctx_cmd);
install_element(CONFIG_NODE, &l23_cfg_ms_cmd);

install_element(MS_NODE, &cfg_ms_apn_cmd);

To view, visit change 32155. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Change-Id: I9476d93954c7dc348e6f97ca89eaa651f802f9a0
Gerrit-Change-Number: 32155
Gerrit-PatchSet: 2
Gerrit-Owner: pespin <pespin@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>
Gerrit-MessageType: merged