osmith has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc-nat/+/27473 )
Change subject: Store MSC
......................................................................
Store MSC
Expect one MSC to be configured in the address book (part of the cs7
section in the config, see doc/examples/osmo-bsc-nat/osmo-bsc-nat.cfg)
and store it on start up.
Store the MSC in a list, as we may potentially support multiple MSCs in
the future. Also that makes it symmetric to the BSC list.
Prepare a FSM for MSC, as the next patch will extend this FSM to send a
RESET to the MSC on start up.
Don't use the stored MSCs in the forwarding logic just yet, a future
commit will replace the current forwarding code with proper connection
mappings.
Related: SYS#5560
Change-Id: I711df0c649728f1007857fbfda500ed5ef69287b
---
M include/osmocom/bsc_nat/Makefile.am
M include/osmocom/bsc_nat/bsc_nat.h
A include/osmocom/bsc_nat/msc_fsm.h
M src/osmo-bsc-nat/Makefile.am
M src/osmo-bsc-nat/bsc_nat.c
M src/osmo-bsc-nat/bsc_nat_fsm.c
M src/osmo-bsc-nat/bssap.c
M src/osmo-bsc-nat/main.c
A src/osmo-bsc-nat/msc_fsm.c
9 files changed, 161 insertions(+), 16 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc-nat refs/changes/73/27473/1
diff --git a/include/osmocom/bsc_nat/Makefile.am b/include/osmocom/bsc_nat/Makefile.am
index 76aada0..4c2bd09 100644
--- a/include/osmocom/bsc_nat/Makefile.am
+++ b/include/osmocom/bsc_nat/Makefile.am
@@ -3,5 +3,6 @@
bsc_nat_fsm.h \
bssap.h \
logging.h \
+ msc_fsm.h \
vty.h \
$(NULL)
diff --git a/include/osmocom/bsc_nat/bsc_nat.h b/include/osmocom/bsc_nat/bsc_nat.h
index eb48f08..0807d83 100644
--- a/include/osmocom/bsc_nat/bsc_nat.h
+++ b/include/osmocom/bsc_nat/bsc_nat.h
@@ -29,6 +29,12 @@
struct osmo_sccp_user *scu;
};
+struct msc {
+ struct llist_head list;
+ struct osmo_sccp_addr addr;
+ struct osmo_fsm_inst *fi;
+};
+
struct bsc {
struct llist_head list;
struct osmo_sccp_addr addr;
@@ -40,12 +46,18 @@
struct bsc_nat_sccp_inst *cn;
struct bsc_nat_sccp_inst *ran;
+ struct llist_head mscs; /* list of struct msc */
struct llist_head bscs; /* list of struct bsc */
};
struct bsc_nat *bsc_nat_alloc(void *tall_ctx);
void bsc_nat_free(struct bsc_nat *bsc_nat);
+struct msc *bsc_nat_msc_add(struct bsc_nat *bsc_nat, struct osmo_sccp_addr *addr);
+struct msc *bsc_nat_msc_add_from_addr_book(struct bsc_nat *bsc_nat);
+struct msc *bsc_nat_msc_get(struct bsc_nat *bsc_nat);
+void bsc_nat_msc_del(struct bsc_nat *bsc_nat, struct msc *msc);
+
struct bsc *bsc_nat_bsc_add(struct bsc_nat *bsc_nat, struct osmo_sccp_addr *addr);
struct bsc *bsc_nat_bsc_get_by_pc(struct bsc_nat *bsc_nat, uint32_t pointcode);
void bsc_nat_bsc_del(struct bsc_nat *bsc_nat, struct bsc *bsc);
diff --git a/include/osmocom/bsc_nat/msc_fsm.h b/include/osmocom/bsc_nat/msc_fsm.h
new file mode 100644
index 0000000..0ea3024
--- /dev/null
+++ b/include/osmocom/bsc_nat/msc_fsm.h
@@ -0,0 +1,21 @@
+/* (C) 2022 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de>
+ * Author: Oliver Smith <osmith(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 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/>.
+ *
+ */
+#pragma once
+
+void msc_fsm_alloc(struct msc *msc);
diff --git a/src/osmo-bsc-nat/Makefile.am b/src/osmo-bsc-nat/Makefile.am
index 445c098..2c2d9fa 100644
--- a/src/osmo-bsc-nat/Makefile.am
+++ b/src/osmo-bsc-nat/Makefile.am
@@ -30,6 +30,7 @@
bssap.c \
logging.c \
main.c \
+ msc_fsm.c \
vty.c \
$(NULL)
diff --git a/src/osmo-bsc-nat/bsc_nat.c b/src/osmo-bsc-nat/bsc_nat.c
index 5a6e84e..b8c87dd 100644
--- a/src/osmo-bsc-nat/bsc_nat.c
+++ b/src/osmo-bsc-nat/bsc_nat.c
@@ -21,6 +21,7 @@
#include <osmocom/bsc_nat/bsc_nat.h>
#include <osmocom/bsc_nat/bsc_nat_fsm.h>
#include <osmocom/bsc_nat/logging.h>
+#include <osmocom/bsc_nat/msc_fsm.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
@@ -39,6 +40,7 @@
OSMO_ASSERT(bsc_nat->ran);
talloc_set_name_const(bsc_nat->ran, "struct bsc_nat_sccp_inst (RAN)");
+ INIT_LLIST_HEAD(&bsc_nat->mscs);
INIT_LLIST_HEAD(&bsc_nat->bscs);
bsc_nat_fsm_alloc(bsc_nat);
@@ -46,6 +48,56 @@
return bsc_nat;
}
+struct msc *bsc_nat_msc_add(struct bsc_nat *bsc_nat, struct osmo_sccp_addr *addr)
+{
+ struct msc *msc = talloc_zero(bsc_nat, struct msc);
+
+ OSMO_ASSERT(msc);
+ talloc_set_name(msc, "MSC(PC=%s)", osmo_ss7_pointcode_print(NULL, addr->pc));
+
+ LOGP(DMAIN, LOGL_DEBUG, "Add %s\n", talloc_get_name(msc));
+
+ msc->addr = *addr;
+
+ INIT_LLIST_HEAD(&msc->list);
+ llist_add(&msc->list, &bsc_nat->mscs);
+
+ msc_fsm_alloc(msc);
+
+ return msc;
+}
+
+struct msc *bsc_nat_msc_add_from_addr_book(struct bsc_nat *bsc_nat)
+{
+ struct osmo_sccp_addr addr;
+
+ /* For now only one MSC is supported */
+ if (osmo_sccp_addr_by_name_local(&addr, "msc", bsc_nat->cn->ss7_inst) < 0) {
+ LOGP(DMAIN, LOGL_ERROR, "Configuration error, MSC not found in address book\n");
+ return NULL;
+ }
+
+ return bsc_nat_msc_add(bsc_nat, &addr);
+}
+
+
+struct msc *bsc_nat_msc_get(struct bsc_nat *bsc_nat)
+{
+ /* For now only one MSC is supported */
+
+ OSMO_ASSERT(!llist_empty(&bsc_nat->mscs));
+
+ return llist_first_entry(&bsc_nat->mscs, struct msc, list);
+}
+
+void bsc_nat_msc_del(struct bsc_nat *bsc_nat, struct msc *msc)
+{
+ LOGP(DMAIN, LOGL_DEBUG, "Del %s\n", talloc_get_name(msc));
+ llist_del(&msc->list);
+ osmo_fsm_inst_free(msc->fi);
+ talloc_free(msc);
+}
+
struct bsc *bsc_nat_bsc_add(struct bsc_nat *bsc_nat, struct osmo_sccp_addr *addr)
{
struct bsc *bsc = talloc_zero(bsc_nat, struct bsc);
@@ -84,6 +136,7 @@
void bsc_nat_free(struct bsc_nat *bsc_nat)
{
+ struct msc *msc;
struct bsc *bsc;
if (bsc_nat->fi) {
@@ -91,6 +144,10 @@
bsc_nat->fi = NULL;
}
+ llist_for_each_entry(msc, &bsc_nat->mscs, list) {
+ bsc_nat_msc_del(bsc_nat, msc);
+ }
+
llist_for_each_entry(bsc, &bsc_nat->bscs, list) {
bsc_nat_bsc_del(bsc_nat, bsc);
}
diff --git a/src/osmo-bsc-nat/bsc_nat_fsm.c b/src/osmo-bsc-nat/bsc_nat_fsm.c
index 3091687..b35376d 100644
--- a/src/osmo-bsc-nat/bsc_nat_fsm.c
+++ b/src/osmo-bsc-nat/bsc_nat_fsm.c
@@ -186,22 +186,7 @@
case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION):
/* connection-less data received */
- addr = &prim->u.unitdata.calling_addr;
-
- if (sccp_sap_get_peer_addr_out(sccp_inst, addr, &peer_addr_out) < 0)
- goto error;
-
- LOGP(DMAIN, LOGL_DEBUG, "Fwd to %s\n", bsc_nat_print_addr(g_bsc_nat->ran, &peer_addr_out));
-
- /* oph->msg stores oph and unitdata msg. Move oph->msg->data to
- * unitdata msg and send it again. */
- msgb_pull_to_l2(oph->msg);
- osmo_sccp_tx_unitdata(g_bsc_nat->ran->scu,
- &g_bsc_nat->ran->addr,
- &peer_addr_out,
- oph->msg->data,
- msgb_length(oph->msg));
- rc = 0;
+ rc = bssap_handle_udt(sccp_inst, &prim->u.unitdata.calling_addr, oph->msg, msgb_l2len(oph->msg));
break;
default:
diff --git a/src/osmo-bsc-nat/bssap.c b/src/osmo-bsc-nat/bssap.c
index af6c8b3..ef12192 100644
--- a/src/osmo-bsc-nat/bssap.c
+++ b/src/osmo-bsc-nat/bssap.c
@@ -20,6 +20,7 @@
#include "config.h"
#include <osmocom/bsc_nat/bsc_nat.h>
#include <osmocom/bsc_nat/logging.h>
+#include <osmocom/bsc_nat/msc_fsm.h>
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/gsm0808.h>
#include <osmocom/sigtran/sccp_helpers.h>
diff --git a/src/osmo-bsc-nat/main.c b/src/osmo-bsc-nat/main.c
index ef4b78d..86a774f 100644
--- a/src/osmo-bsc-nat/main.c
+++ b/src/osmo-bsc-nat/main.c
@@ -199,6 +199,9 @@
bsc_nat_fsm_start(g_bsc_nat);
+ if (!bsc_nat_msc_add_from_addr_book(g_bsc_nat))
+ exit(1);
+
while (!osmo_select_shutdown_done())
osmo_select_main_ctx(0);
diff --git a/src/osmo-bsc-nat/msc_fsm.c b/src/osmo-bsc-nat/msc_fsm.c
new file mode 100644
index 0000000..30434f4
--- /dev/null
+++ b/src/osmo-bsc-nat/msc_fsm.c
@@ -0,0 +1,64 @@
+/* (C) 2022 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de>
+ * Author: Oliver Smith <osmith(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 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 "config.h"
+#include <osmocom/bsc_nat/bsc_nat.h>
+#include <osmocom/bsc_nat/bssap.h>
+#include <osmocom/bsc_nat/logging.h>
+#include <osmocom/core/fsm.h>
+#include <osmocom/sigtran/sccp_sap.h>
+
+#define X(s) (1 << (s))
+
+enum msc_fsm_states {
+ MSC_FSM_ST_DISCONNECTED,
+};
+
+static struct osmo_fsm_state msc_fsm_states[] = {
+ [MSC_FSM_ST_DISCONNECTED] = {
+ .name = "DISCONNECTED",
+ .in_event_mask = 0
+ ,
+ .out_state_mask = 0
+ ,
+ },
+};
+
+const struct value_string msc_fsm_event_names[] = {
+ { 0, NULL }
+};
+
+struct osmo_fsm msc_fsm = {
+ .name = "MSC",
+ .states = msc_fsm_states,
+ .num_states = ARRAY_SIZE(msc_fsm_states),
+ .log_subsys = DMAIN,
+ .event_names = msc_fsm_event_names,
+};
+
+static __attribute__((constructor)) void msc_fsm_init(void)
+{
+ OSMO_ASSERT(osmo_fsm_register(&msc_fsm) == 0);
+}
+
+void msc_fsm_alloc(struct msc *msc)
+{
+ msc->fi = osmo_fsm_inst_alloc(&msc_fsm, msc, msc, LOGL_INFO, NULL);
+ OSMO_ASSERT(msc->fi);
+}
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc-nat/+/27473
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc-nat
Gerrit-Branch: master
Gerrit-Change-Id: I711df0c649728f1007857fbfda500ed5ef69287b
Gerrit-Change-Number: 27473
Gerrit-PatchSet: 1
Gerrit-Owner: osmith <osmith(a)sysmocom.de>
Gerrit-MessageType: newchange
osmith has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc-nat/+/27471 )
Change subject: Reply to BSC's RESET with RESET ACK directly
......................................................................
Reply to BSC's RESET with RESET ACK directly
Let the BSCNAT directly reply to RESET sent from BSC with RESET ACK.
bssap_ran_handle_reset() is a bit empty right now but will be used in a
future patch to store the BSC.
Related: SYS#5560
Related: https://osmocom.org/projects/osmo-bscnat/wiki/AoIP_OsmoBSCNAT#RESET
Change-Id: I3223409e25c93b625d67634caf68efe9772e2558
---
M include/osmocom/bsc_nat/Makefile.am
A include/osmocom/bsc_nat/bssap.h
M src/osmo-bsc-nat/Makefile.am
M src/osmo-bsc-nat/bsc_nat_fsm.c
A src/osmo-bsc-nat/bssap.c
5 files changed, 133 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc-nat refs/changes/71/27471/1
diff --git a/include/osmocom/bsc_nat/Makefile.am b/include/osmocom/bsc_nat/Makefile.am
index 90f44a7..76aada0 100644
--- a/include/osmocom/bsc_nat/Makefile.am
+++ b/include/osmocom/bsc_nat/Makefile.am
@@ -1,6 +1,7 @@
noinst_HEADERS = \
bsc_nat.h \
bsc_nat_fsm.h \
+ bssap.h \
logging.h \
vty.h \
$(NULL)
diff --git a/include/osmocom/bsc_nat/bssap.h b/include/osmocom/bsc_nat/bssap.h
new file mode 100644
index 0000000..1a9324a
--- /dev/null
+++ b/include/osmocom/bsc_nat/bssap.h
@@ -0,0 +1,24 @@
+/* (C) 2022 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de>
+ * Author: Oliver Smith <osmith(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 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/>.
+ *
+ */
+#pragma once
+
+#include <osmocom/bsc_nat/bsc_nat.h>
+
+int bssap_handle_udt(struct bsc_nat_sccp_inst *sccp_inst, struct osmo_sccp_addr *addr, struct msgb *msgb,
+ unsigned int length);
diff --git a/src/osmo-bsc-nat/Makefile.am b/src/osmo-bsc-nat/Makefile.am
index 6a759cb..445c098 100644
--- a/src/osmo-bsc-nat/Makefile.am
+++ b/src/osmo-bsc-nat/Makefile.am
@@ -27,6 +27,7 @@
osmo_bsc_nat_SOURCES = \
bsc_nat.c \
bsc_nat_fsm.c \
+ bssap.c \
logging.c \
main.c \
vty.c \
diff --git a/src/osmo-bsc-nat/bsc_nat_fsm.c b/src/osmo-bsc-nat/bsc_nat_fsm.c
index aa15c06..3091687 100644
--- a/src/osmo-bsc-nat/bsc_nat_fsm.c
+++ b/src/osmo-bsc-nat/bsc_nat_fsm.c
@@ -21,6 +21,7 @@
#include <errno.h>
#include <osmocom/bsc_nat/bsc_nat.h>
#include <osmocom/bsc_nat/bsc_nat_fsm.h>
+#include <osmocom/bsc_nat/bssap.h>
#include <osmocom/bsc_nat/logging.h>
#include <osmocom/core/fsm.h>
#include <osmocom/core/select.h>
@@ -299,6 +300,10 @@
case OSMO_PRIM(OSMO_SCU_PRIM_N_UNITDATA, PRIM_OP_INDICATION):
/* connection-less data received */
+ rc = bssap_handle_udt(sccp_inst, &prim->u.unitdata.calling_addr, oph->msg, msgb_l2len(oph->msg));
+
+ /* FIXME: don't forward this to the MSC anymore, as soon as the
+ * BSCNAT is able to do the RESET to MSC by itself. */
addr = &prim->u.unitdata.calling_addr;
if (sccp_sap_get_peer_addr_out(sccp_inst, addr, &peer_addr_out) < 0)
@@ -314,7 +319,6 @@
&peer_addr_out,
oph->msg->data,
msgb_length(oph->msg));
- rc = 0;
break;
default:
diff --git a/src/osmo-bsc-nat/bssap.c b/src/osmo-bsc-nat/bssap.c
new file mode 100644
index 0000000..dfeea73
--- /dev/null
+++ b/src/osmo-bsc-nat/bssap.c
@@ -0,0 +1,102 @@
+/* (C) 2022 by sysmocom - s.f.m.c. GmbH <info(a)sysmocom.de>
+ * Author: Oliver Smith <osmith(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 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 "config.h"
+#include <osmocom/bsc_nat/bsc_nat.h>
+#include <osmocom/bsc_nat/logging.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/gsm/gsm0808.h>
+#include <osmocom/sigtran/sccp_helpers.h>
+#include <osmocom/sigtran/sccp_sap.h>
+
+static int tx_reset_ack(struct bsc_nat_sccp_inst *sccp_inst, struct osmo_sccp_addr *addr)
+{
+ LOGP(DMAIN, LOGL_NOTICE, "Tx RESET ACK to %s\n", bsc_nat_print_addr(sccp_inst, addr));
+
+ struct msgb *msg = gsm0808_create_reset_ack();
+
+ return osmo_sccp_tx_unitdata_msg(sccp_inst->scu, &sccp_inst->addr, addr, msg);
+}
+
+static int bssap_ran_handle_reset(struct osmo_sccp_addr *addr, struct msgb *msg, unsigned int length)
+{
+ LOGP(DMAIN, LOGL_NOTICE, "Rx RESET from %s\n", bsc_nat_print_addr(g_bsc_nat->ran, addr));
+ return tx_reset_ack(g_bsc_nat->ran, addr);
+}
+
+static int bssap_ran_rcvmsg_udt(struct osmo_sccp_addr *addr, struct msgb *msg, unsigned int length)
+{
+ int ret = 0;
+
+ switch (msg->l3h[0]) {
+ case BSS_MAP_MSG_RESET:
+ ret = bssap_ran_handle_reset(addr, msg, length);
+ break;
+ default:
+ LOGP(DMAIN, LOGL_NOTICE, "Unimplemented BSSMAP UDT %s\n", gsm0808_bssap_name(msg->l3h[0]));
+ break;
+ }
+
+ return ret;
+}
+
+static int bssap_rcvmsg_udt(struct bsc_nat_sccp_inst *sccp_inst, struct osmo_sccp_addr *addr, struct msgb *msg,
+ unsigned int length)
+{
+ if (length < 1) {
+ LOGP(DMAIN, LOGL_ERROR, "Not enough room: %u\n", length);
+ return -1;
+ }
+
+ LOGP(DMAIN, LOGL_NOTICE, "Rx UDT BSSMAP %s\n", gsm0808_bssap_name(msg->l3h[0]));
+
+ /* NOTE: bssap_cn_rcvmsg_udt() will be added in a future patch */
+ return bssap_ran_rcvmsg_udt(addr, msg, length - sizeof(struct bssmap_header));
+}
+
+int bssap_handle_udt(struct bsc_nat_sccp_inst *sccp_inst, struct osmo_sccp_addr *addr, struct msgb *msgb,
+ unsigned int length)
+{
+ struct bssmap_header *bs;
+ int rc = -1;
+
+ LOGP(DMAIN, LOGL_DEBUG, "Rx UDT: %s\n", osmo_hexdump(msgb->l2h, length));
+
+ if (length < sizeof(*bs)) {
+ LOGP(DMAIN, LOGL_ERROR, "The header is too short\n");
+ return -1;
+ }
+
+ bs = (struct bssmap_header *)msgb->l2h;
+ if (bs->length < length - sizeof(*bs)) {
+ LOGP(DMAIN, LOGL_ERROR, "Failed to parse BSSMAP header\n");
+ return -1;
+ }
+
+ switch (bs->type) {
+ case BSSAP_MSG_BSS_MANAGEMENT:
+ msgb->l3h = &msgb->l2h[sizeof(*bs)];
+ rc = bssap_rcvmsg_udt(sccp_inst, addr, msgb, length - sizeof(*bs));
+ break;
+ default:
+ LOGP(DMAIN, LOGL_NOTICE, "Unimplemented msg type: %s\n", gsm0808_bssap_name(bs->type));
+ }
+
+ return rc;
+}
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc-nat/+/27471
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc-nat
Gerrit-Branch: master
Gerrit-Change-Id: I3223409e25c93b625d67634caf68efe9772e2558
Gerrit-Change-Number: 27471
Gerrit-PatchSet: 1
Gerrit-Owner: osmith <osmith(a)sysmocom.de>
Gerrit-MessageType: newchange