<p>pespin <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-hnodeb/+/25995">View Change</a></p><div style="white-space:pre-wrap">Approvals:
pespin: Looks good to me, approved; Verified
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Import hnb-test from osmo-iuh.git<br><br>Import from osmo-iuh.git Change-Id Iba106dcc18e3d429b4b9808610a44ac29b798172,<br>with minimal renaming of s/hnb_test/hnb/ and required mangling to have<br>it compile and run.<br><br>Change-Id: I36fd4aa5d39222371bd36e9f540b91e36a26de43<br>---<br>M configure.ac<br>M contrib/jenkins.sh<br>M include/osmocom/hnodeb/Makefile.am<br>M include/osmocom/hnodeb/hnodeb.h<br>A include/osmocom/hnodeb/ranap.h<br>A include/osmocom/hnodeb/rua.h<br>M src/osmo-hnodeb/Makefile.am<br>A src/osmo-hnodeb/debug.c<br>M src/osmo-hnodeb/main.c<br>A src/osmo-hnodeb/ranap.c<br>A src/osmo-hnodeb/rua.c<br>11 files changed, 1,383 insertions(+), 4 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/configure.ac b/configure.ac</span><br><span>index 171f998..5b4ca8b 100644</span><br><span>--- a/configure.ac</span><br><span>+++ b/configure.ac</span><br><span>@@ -55,6 +55,7 @@</span><br><span> AC_MSG_ERROR([sctp_recvmsg not found in searched libs])])</span><br><span> LIBS=$old_LIBS</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+PKG_CHECK_MODULES(LIBASN1C, libasn1c >= 0.9.30)</span><br><span> PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.5.0)</span><br><span> PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.5.0)</span><br><span> PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.5.0)</span><br><span>@@ -62,6 +63,10 @@</span><br><span> PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.1.0)</span><br><span> PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.1.0)</span><br><span> PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.4.0)</span><br><span style="color: hsl(120, 100%, 40%);">+PKG_CHECK_MODULES(LIBOSMORUA, libosmo-rua >= 0.7.0)</span><br><span style="color: hsl(120, 100%, 40%);">+PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap >= 0.7.0)</span><br><span style="color: hsl(120, 100%, 40%);">+PKG_CHECK_MODULES(LIBOSMOHNBAP, libosmo-hnbap >= 0.7.0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> </span><br><span> dnl checks for header files</span><br><span> AC_HEADER_STDC</span><br><span>diff --git a/contrib/jenkins.sh b/contrib/jenkins.sh</span><br><span>index 85042d8..7001013 100755</span><br><span>--- a/contrib/jenkins.sh</span><br><span>+++ b/contrib/jenkins.sh</span><br><span>@@ -34,6 +34,7 @@</span><br><span> osmo-build-dep.sh libosmo-netif</span><br><span> osmo-build-dep.sh libosmo-sccp</span><br><span> osmo-build-dep.sh libasn1c</span><br><span style="color: hsl(120, 100%, 40%);">+osmo-build-dep.sh osmo-iuh</span><br><span> </span><br><span> # Additional configure options and depends</span><br><span> CONFIG=""</span><br><span>@@ -51,12 +52,12 @@</span><br><span> </span><br><span> cd "$base"</span><br><span> autoreconf --install --force</span><br><span style="color: hsl(0, 100%, 40%);">-./configure --enable-sanitize --enable-external-tests --enable-werror $CONFIG</span><br><span style="color: hsl(120, 100%, 40%);">+./configure --enable-sanitize --enable-external-tests $CONFIG</span><br><span> $MAKE $PARALLEL_MAKE</span><br><span> LD_LIBRARY_PATH="$inst/lib" $MAKE check \</span><br><span> || cat-testlogs.sh</span><br><span> LD_LIBRARY_PATH="$inst/lib" \</span><br><span style="color: hsl(0, 100%, 40%);">- DISTCHECK_CONFIGURE_FLAGS="--enable-vty-tests --enable-external-tests --enable-werror $CONFIG" \</span><br><span style="color: hsl(120, 100%, 40%);">+ DISTCHECK_CONFIGURE_FLAGS="--enable-vty-tests --enable-external-tests $CONFIG" \</span><br><span> $MAKE $PARALLEL_MAKE distcheck \</span><br><span> || cat-testlogs.sh</span><br><span> </span><br><span>diff --git a/include/osmocom/hnodeb/Makefile.am b/include/osmocom/hnodeb/Makefile.am</span><br><span>index 189ef37..9f8963a 100644</span><br><span>--- a/include/osmocom/hnodeb/Makefile.am</span><br><span>+++ b/include/osmocom/hnodeb/Makefile.am</span><br><span>@@ -1,3 +1,5 @@</span><br><span> noinst_HEADERS = \</span><br><span> hnodeb.h \</span><br><span style="color: hsl(120, 100%, 40%);">+ ranap.h \</span><br><span style="color: hsl(120, 100%, 40%);">+ rua.h \</span><br><span> $(NULL)</span><br><span>diff --git a/include/osmocom/hnodeb/hnodeb.h b/include/osmocom/hnodeb/hnodeb.h</span><br><span>index 6f70f09..ef11ab7 100644</span><br><span>--- a/include/osmocom/hnodeb/hnodeb.h</span><br><span>+++ b/include/osmocom/hnodeb/hnodeb.h</span><br><span>@@ -1 +1,104 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2015 by Daniel Willmann <dwillmann@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Pau Espin Pedrol <pespin@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU Affero General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program. If not, see <http://www.gnu.org/lienses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span> #pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/select.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/linuxlist.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/write_queue.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum {</span><br><span style="color: hsl(120, 100%, 40%);">+ DMAIN,</span><br><span style="color: hsl(120, 100%, 40%);">+ DHNBAP,</span><br><span style="color: hsl(120, 100%, 40%);">+ DRUA,</span><br><span style="color: hsl(120, 100%, 40%);">+ DRANAP,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+extern const struct log_info hnb_log_info;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 25.467 Section 7.1 */</span><br><span style="color: hsl(120, 100%, 40%);">+#define IUH_DEFAULT_SCTP_PORT 29169</span><br><span style="color: hsl(120, 100%, 40%);">+#define RNA_DEFAULT_SCTP_PORT 25471</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define IUH_PPI_RUA 19</span><br><span style="color: hsl(120, 100%, 40%);">+#define IUH_PPI_HNBAP 20</span><br><span style="color: hsl(120, 100%, 40%);">+#define IUH_PPI_SABP 31</span><br><span style="color: hsl(120, 100%, 40%);">+#define IUH_PPI_RNA 42</span><br><span style="color: hsl(120, 100%, 40%);">+#define IUH_PPI_PUA 55</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define IUH_MSGB_SIZE 2048</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct umts_cell_id {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t mcc; /*!< Mobile Country Code */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t mnc; /*!< Mobile Network Code */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t lac; /*!< Locaton Area Code */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t rac; /*!< Routing Area Code */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t sac; /*!< Service Area Code */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t cid; /*!< Cell ID */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct ue_context {</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! Entry in the HNB-global list of UE */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head list;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! Unique Context ID for this UE */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t context_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ char imsi[16+1];</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hnb_chan {</span><br><span style="color: hsl(120, 100%, 40%);">+ int is_ps;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t conn_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *imsi;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hnb {</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *gw_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t gw_port;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! SCTP listen socket for incoming connections */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_fd conn_fd;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! SCTP socket + write queue for Iuh to this specific HNB */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_wqueue wqueue;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! copied from HNB-Identity-Info IE */</span><br><span style="color: hsl(120, 100%, 40%);">+ char identity_info[256];</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! copied from Cell Identity IE */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct umts_cell_id id;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! SCTP stream ID for HNBAP */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t hnbap_stream;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! SCTP stream ID for RUA */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t rua_stream;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t rnc_id;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t ctx_id;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ int ues;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_chan *chan;</span><br><span style="color: hsl(120, 100%, 40%);">+ } cs;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rx_iu_release(struct hnb *hnb);</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rx_paging(struct hnb *hnb, const char *imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_nas_rx_dtap(struct hnb *hnb, void *data, int len);</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rx_secmode_cmd(struct hnb *hnb, long ip_alg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern struct hnb g_hnb;</span><br><span>diff --git a/include/osmocom/hnodeb/ranap.h b/include/osmocom/hnodeb/ranap.h</span><br><span>new file mode 100644</span><br><span>index 0000000..f68006f</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/hnodeb/ranap.h</span><br><span>@@ -0,0 +1,26 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2015 by Daniel Willmann <dwillmann@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Pau Espin Pedrol <pespin@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU Affero General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program. If not, see <http://www.gnu.org/lienses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct ranap_message_s;</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnodeb/hnodeb.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rua_dt_handle_ranap(struct hnb *hnb, struct ranap_message_s *ranap_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rua_cl_handle_ranap(struct hnb *hnb, struct ranap_message_s *ranap_msg);</span><br><span>diff --git a/include/osmocom/hnodeb/rua.h b/include/osmocom/hnodeb/rua.h</span><br><span>new file mode 100644</span><br><span>index 0000000..28d0a1a</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/hnodeb/rua.h</span><br><span>@@ -0,0 +1,27 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2015 by Daniel Willmann <dwillmann@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Pau Espin Pedrol <pespin@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU Affero General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program. If not, see <http://www.gnu.org/lienses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <asn1c/ANY.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hnb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rua_dt_handle(struct hnb *hnb, struct ANY *in);</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rua_cl_handle(struct hnb *hnb, struct ANY *in);</span><br><span>diff --git a/src/osmo-hnodeb/Makefile.am b/src/osmo-hnodeb/Makefile.am</span><br><span>index 8807436..9f09a0a 100644</span><br><span>--- a/src/osmo-hnodeb/Makefile.am</span><br><span>+++ b/src/osmo-hnodeb/Makefile.am</span><br><span>@@ -6,6 +6,7 @@</span><br><span> </span><br><span> AM_CFLAGS = \</span><br><span> -Wall \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(LIBASN1C_CFLAGS) \</span><br><span> $(LIBOSMOCORE_CFLAGS) \</span><br><span> $(LIBOSMOGSM_CFLAGS) \</span><br><span> $(LIBOSMOVTY_CFLAGS) \</span><br><span>@@ -14,6 +15,9 @@</span><br><span> $(COVERAGE_CFLAGS) \</span><br><span> $(LIBOSMOABIS_CFLAGS) \</span><br><span> $(LIBOSMOSIGTRAN_CFLAGS) \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(LIBOSMORUA_CFLAGS) \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(LIBOSMORANAP_CFLAGS) \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(LIBOSMOHNBAP_CFLAGS) \</span><br><span> $(NULL)</span><br><span> </span><br><span> AM_LDFLAGS = \</span><br><span>@@ -26,9 +30,13 @@</span><br><span> </span><br><span> osmo_hnodeb_SOURCES = \</span><br><span> main.c \</span><br><span style="color: hsl(120, 100%, 40%);">+ debug.c \</span><br><span style="color: hsl(120, 100%, 40%);">+ ranap.c \</span><br><span style="color: hsl(120, 100%, 40%);">+ rua.c \</span><br><span> $(NULL)</span><br><span> </span><br><span> osmo_hnodeb_LDADD = \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(LIBASN1C_LIBS) \</span><br><span> $(LIBOSMOCORE_LIBS) \</span><br><span> $(LIBOSMOGSM_LIBS) \</span><br><span> $(LIBOSMOVTY_LIBS) \</span><br><span>@@ -37,5 +45,8 @@</span><br><span> $(COVERAGE_LDFLAGS) \</span><br><span> $(LIBOSMOABIS_LIBS) \</span><br><span> $(LIBOSMOSIGTRAN_LIBS) \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(LIBOSMORUA_LIBS) \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(LIBOSMORANAP_LIBS) \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(LIBOSMOHNBAP_LIBS) \</span><br><span> $(LIBSCTP_LIBS) \</span><br><span> $(NULL)</span><br><span>diff --git a/src/osmo-hnodeb/debug.c b/src/osmo-hnodeb/debug.c</span><br><span>new file mode 100644</span><br><span>index 0000000..69c369e</span><br><span>--- /dev/null</span><br><span>+++ b/src/osmo-hnodeb/debug.c</span><br><span>@@ -0,0 +1,50 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2015 by Daniel Willmann <dwillmann@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Pau Espin Pedrol <pespin@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU Affero General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program. If not, see <http://www.gnu.org/lienses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnodeb/hnodeb.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct log_info_cat log_cat[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ [DMAIN] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "DMAIN", .loglevel = LOGL_INFO, .enabled = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .color = "",</span><br><span style="color: hsl(120, 100%, 40%);">+ .description = "Main program",</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ [DHNBAP] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "DHNBAP", .loglevel = LOGL_DEBUG, .enabled = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .color = "",</span><br><span style="color: hsl(120, 100%, 40%);">+ .description = "Home Node B Application Part",</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ [DRANAP] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "RANAP", .loglevel = LOGL_DEBUG, .enabled = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .color = "",</span><br><span style="color: hsl(120, 100%, 40%);">+ .description = "RAN Application Part",</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ [DRUA] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "RUA", .loglevel = LOGL_DEBUG, .enabled = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .color = "",</span><br><span style="color: hsl(120, 100%, 40%);">+ .description = "RANAP User Adaptation",</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const struct log_info hnb_log_info = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .cat = log_cat,</span><br><span style="color: hsl(120, 100%, 40%);">+ .num_cat = ARRAY_SIZE(log_cat),</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span>diff --git a/src/osmo-hnodeb/main.c b/src/osmo-hnodeb/main.c</span><br><span>index 96d9136..9a2aaf9 100644</span><br><span>--- a/src/osmo-hnodeb/main.c</span><br><span>+++ b/src/osmo-hnodeb/main.c</span><br><span>@@ -1,4 +1,5 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2015 by Daniel Willmann <dwillmann@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span> * Author: Pau Espin Pedrol <pespin@sysmocom.de></span><br><span> * All Rights Reserved</span><br><span> *</span><br><span>@@ -19,7 +20,992 @@</span><br><span> </span><br><span> #include "config.h"</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <unistd.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <getopt.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <signal.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/types.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/socket.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <netinet/in.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <netinet/sctp.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arpa/inet.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/application.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/talloc.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/select.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/socket.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/write_queue.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/netif/stream.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/tlv.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsm48.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/vty/telnet_interface.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/vty/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/vty/command.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/crypt/auth.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnbap/hnbap_common.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnbap/hnbap_ies_defs.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/rua/rua_msg_factory.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "asn1helpers.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ranap/iu_helpers.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ranap/ranap_msg_factory.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/rua/RUA_RUA-PDU.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/protocol/gsm_04_08.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ranap/RANAP_ProcedureCode.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ranap/RANAP_Criticality.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ranap/RANAP_DirectTransfer.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ranap/ranap_common.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnodeb/rua.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnodeb/ranap.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnodeb/hnodeb.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void *tall_hnb_ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hnb g_hnb = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .gw_addr = "127.0.0.1",</span><br><span style="color: hsl(120, 100%, 40%);">+ .gw_port = IUH_DEFAULT_SCTP_PORT,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb *rua_new_udt(struct msgb *inmsg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#if 0</span><br><span style="color: hsl(120, 100%, 40%);">+static int hnb_ue_de_register_tx(struct hnb *hnb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t ctx_id;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ UEDe_Register_t dereg;</span><br><span style="color: hsl(120, 100%, 40%);">+ UEDe_RegisterIEs_t dereg_ies;</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&dereg_ies, 0, sizeof(dereg_ies));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ asn1_u24_to_bitstring(&dereg_ies.context_ID, &ctx_id, hnb->ctx_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ dereg_ies.cause.present = Cause_PR_radioNetwork;</span><br><span style="color: hsl(120, 100%, 40%);">+ dereg_ies.cause.choice.radioNetwork = CauseRadioNetwork_connection_with_UE_lost;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&dereg, 0, sizeof(dereg));</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = hnbap_encode_uede_registeries(&dereg, &dereg_ies);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(rc == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = hnbap_generate_initiating_message(ProcedureCode_id_UEDe_Register,</span><br><span style="color: hsl(120, 100%, 40%);">+ Criticality_ignore,</span><br><span style="color: hsl(120, 100%, 40%);">+ &asn_DEF_UEDe_Register,</span><br><span style="color: hsl(120, 100%, 40%);">+ &dereg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_UEDe_Register, &dereg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_sctp_ppid(msg) = IUH_PPI_HNBAP;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return osmo_wqueue_enqueue(&hnb->wqueue, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int hnb_ue_register_tx(struct hnb *hnb, const char *imsi_str)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc, imsi_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t imsi_buf[16];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ HNBAP_UERegisterRequest_t request_out;</span><br><span style="color: hsl(120, 100%, 40%);">+ HNBAP_UERegisterRequestIEs_t request;</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&request, 0, sizeof(request));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ request.uE_Identity.present = HNBAP_UE_Identity_PR_iMSI;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ imsi_len = ranap_imsi_encode(imsi_buf, sizeof(imsi_buf), imsi_str);</span><br><span style="color: hsl(120, 100%, 40%);">+ OCTET_STRING_fromBuf(&request.uE_Identity.choice.iMSI, (const char*)imsi_buf, imsi_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ request.registration_Cause = HNBAP_Registration_Cause_normal;</span><br><span style="color: hsl(120, 100%, 40%);">+ request.uE_Capabilities.access_stratum_release_indicator = HNBAP_Access_stratum_release_indicator_rel_6;</span><br><span style="color: hsl(120, 100%, 40%);">+ request.uE_Capabilities.csg_capability = HNBAP_CSG_Capability_not_csg_capable;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&request_out, 0, sizeof(request_out));</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = hnbap_encode_ueregisterrequesties(&request_out, &request);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(rc == 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = hnbap_generate_initiating_message(HNBAP_ProcedureCode_id_UERegister,</span><br><span style="color: hsl(120, 100%, 40%);">+ HNBAP_Criticality_reject,</span><br><span style="color: hsl(120, 100%, 40%);">+ &asn_DEF_HNBAP_UERegisterRequest,</span><br><span style="color: hsl(120, 100%, 40%);">+ &request_out);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_HNBAP_UERegisterRequest, &request_out);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_sctp_ppid(msg) = IUH_PPI_HNBAP;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return osmo_wqueue_enqueue(&hnb->wqueue, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int hnb_rx_hnb_register_acc(struct hnb *hnb, ANY_t *in)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ HNBAP_HNBRegisterAcceptIEs_t accept;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = hnbap_decode_hnbregisteraccepties(&accept, in);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->rnc_id = accept.rnc_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("HNB Register accept with RNC ID %u\n", hnb->rnc_id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ hnbap_free_hnbregisteraccepties(&accept);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int hnb_rx_ue_register_acc(struct hnb *hnb, ANY_t *in)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t ctx_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ HNBAP_UERegisterAcceptIEs_t accept;</span><br><span style="color: hsl(120, 100%, 40%);">+ char imsi[16];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = hnbap_decode_ueregisteraccepties(&accept, in);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (accept.uE_Identity.present != HNBAP_UE_Identity_PR_iMSI) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Wrong type in UE register accept\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ctx_id = asn1bitstr_to_u24(&accept.context_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ranap_bcd_decode(imsi, sizeof(imsi), accept.uE_Identity.choice.iMSI.buf,</span><br><span style="color: hsl(120, 100%, 40%);">+ accept.uE_Identity.choice.iMSI.size);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("UE Register accept for IMSI %s, context %u\n", imsi, ctx_id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->ctx_id = ctx_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ hnbap_free_ueregisteraccepties(&accept);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *gen_nas_id_resp()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t id_resp[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ GSM48_PDISC_MM,</span><br><span style="color: hsl(120, 100%, 40%);">+ GSM48_MT_MM_ID_RESP,</span><br><span style="color: hsl(120, 100%, 40%);">+ /* IMEISV */</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x09, /* len */</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x03, /* first digit (0000) + even (0) + id IMEISV (011) */</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x31, 0x91, 0x06, 0x00, 0x28, 0x47, 0x11, /* digits */</span><br><span style="color: hsl(120, 100%, 40%);">+ 0xf2, /* filler (1111) + last digit (0010) */</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return ranap_new_msg_dt(0, id_resp, sizeof(id_resp));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *gen_nas_tmsi_realloc_compl()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t id_resp[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ GSM48_PDISC_MM,</span><br><span style="color: hsl(120, 100%, 40%);">+ GSM48_MT_MM_TMSI_REALL_COMPL,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return ranap_new_msg_dt(0, id_resp, sizeof(id_resp));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *gen_nas_auth_resp(uint8_t *sres)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t id_resp[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ GSM48_PDISC_MM,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x80 | GSM48_MT_MM_AUTH_RESP, /* simulate sequence nr 2 */</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x61, 0xb5, 0x69, 0xf5 /* hardcoded SRES */</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(id_resp + 2, sres, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return ranap_new_msg_dt(0, id_resp, sizeof(id_resp));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int hnb_tx_dt(struct hnb *hnb, struct msgb *txm)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_chan *chan;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *rua;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ chan = hnb->cs.chan;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!chan) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("hnb_nas_tx_tmsi_realloc_compl(): No CS channel established yet.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rua = rua_new_dt(chan->is_ps, chan->conn_id, txm);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_wqueue_enqueue(&g_hnb.wqueue, rua);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct tlv_parsed *parse_mm(struct gsm48_hdr *gh, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ static struct tlv_parsed tp;</span><br><span style="color: hsl(120, 100%, 40%);">+ int parse_res;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ len -= (const char *)&gh->data[0] - (const char *)gh;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(gsm48_hdr_pdisc(gh) == GSM48_PDISC_MM);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ parse_res = tlv_parse(&tp, &gsm48_mm_att_tlvdef, &gh->data[0], len, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (parse_res <= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t msg_type = gsm48_hdr_msg_type(gh);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Error parsing MM message 0x%hhx: %d\n", msg_type, parse_res);</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return &tp;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int hnb_nas_rx_lu_accept(struct gsm48_hdr *gh, int len, int *sent_tmsi)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ printf(" :D Location Update Accept :D\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm48_loc_area_id *lai;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ lai = (struct gsm48_loc_area_id *)&gh->data[0];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_location_area_id laid;</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm48_decode_lai2(lai, &laid);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("LU: mcc %s mnc %s lac %hd\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_mcc_name(laid.plmn.mcc), osmo_mnc_name(laid.plmn.mnc, laid.plmn.mnc_3_digits),</span><br><span style="color: hsl(120, 100%, 40%);">+ laid.lac);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct tlv_parsed tp;</span><br><span style="color: hsl(120, 100%, 40%);">+ int parse_res;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ len -= (const char *)&gh->data[0] - (const char *)gh;</span><br><span style="color: hsl(120, 100%, 40%);">+ parse_res = tlv_parse(&tp, &gsm48_mm_att_tlvdef, &gh->data[0], len, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (parse_res <= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Error parsing Location Update Accept message: %d\n", parse_res);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t type = TLVP_VAL(&tp, GSM48_IE_NAME_SHORT)[0] & 0x0f;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (type == GSM_MI_TYPE_TMSI)</span><br><span style="color: hsl(120, 100%, 40%);">+ *sent_tmsi = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ else *sent_tmsi = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_nas_rx_mm_info(struct gsm48_hdr *gh, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ printf(" :) MM Info :)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ struct tlv_parsed *tp = parse_mm(gh, len);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!tp)</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (TLVP_PRESENT(tp, GSM48_IE_NAME_SHORT)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ char name[128] = {0};</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm_7bit_decode_n(name, 127,</span><br><span style="color: hsl(120, 100%, 40%);">+ TLVP_VAL(tp, GSM48_IE_NAME_SHORT)+1,</span><br><span style="color: hsl(120, 100%, 40%);">+ (TLVP_LEN(tp, GSM48_IE_NAME_SHORT)-1)*8/7);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Info: Short Network Name: %s\n", name);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (TLVP_PRESENT(tp, GSM48_IE_NAME_LONG)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ char name[128] = {0};</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm_7bit_decode_n(name, 127,</span><br><span style="color: hsl(120, 100%, 40%);">+ TLVP_VAL(tp, GSM48_IE_NAME_LONG)+1,</span><br><span style="color: hsl(120, 100%, 40%);">+ (TLVP_LEN(tp, GSM48_IE_NAME_LONG)-1)*8/7);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Info: Long Network Name: %s\n", name);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int hnb_nas_rx_auth_req(struct hnb *hnb, struct gsm48_hdr *gh,</span><br><span style="color: hsl(120, 100%, 40%);">+ int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm48_auth_req *ar;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ len -= (const char *)&gh->data[0] - (const char *)gh;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (len < sizeof(*ar)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("GSM48 Auth Req does not fit.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf(" :) Authentication Request :)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ar = (struct gsm48_auth_req*) &gh->data[0];</span><br><span style="color: hsl(120, 100%, 40%);">+ int seq = ar->key_seq;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Generate SRES from *HARDCODED* Ki for Iuh testing */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_auth_vector vec;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Ki 000102030405060708090a0b0c0d0e0f */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_sub_auth_data auth = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .type = OSMO_AUTH_TYPE_GSM,</span><br><span style="color: hsl(120, 100%, 40%);">+ .algo = OSMO_AUTH_ALG_COMP128v1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .u.gsm.ki = {</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x0e, 0x0f</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&vec, 0, sizeof(vec));</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_auth_gen_vec(&vec, &auth, ar->rand);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("seq %d rand %s",</span><br><span style="color: hsl(120, 100%, 40%);">+ seq, osmo_hexdump(ar->rand, sizeof(ar->rand)));</span><br><span style="color: hsl(120, 100%, 40%);">+ printf(" --> sres %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_hexdump(vec.sres, 4));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return hnb_tx_dt(hnb, gen_nas_auth_resp(vec.sres));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_tx_iu_release_req(struct hnb *hnb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ RANAP_Cause_t cause = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .present = RANAP_Cause_PR_radioNetwork,</span><br><span style="color: hsl(120, 100%, 40%);">+ .choice.transmissionNetwork = RANAP_CauseRadioNetwork_release_due_to_UE_generated_signalling_connection_release,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_tx_dt(hnb, ranap_new_msg_iu_rel_req(&cause));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_tx_iu_release_compl(struct hnb *hnb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_tx_dt(hnb, ranap_new_msg_iu_rel_compl());</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int hnb_nas_rx_mm(struct hnb *hnb, struct gsm48_hdr *gh, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_chan *chan;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ chan = hnb->cs.chan;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!chan) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("hnb_nas_rx_mm(): No CS channel established yet.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(!chan->is_ps);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t msg_type = gsm48_hdr_msg_type(gh);</span><br><span style="color: hsl(120, 100%, 40%);">+ int sent_tmsi;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (msg_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM48_MT_MM_ID_REQ:</span><br><span style="color: hsl(120, 100%, 40%);">+ return hnb_tx_dt(hnb, gen_nas_id_resp());</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM48_MT_MM_LOC_UPD_ACCEPT:</span><br><span style="color: hsl(120, 100%, 40%);">+ if (hnb_nas_rx_lu_accept(gh, len, &sent_tmsi))</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (sent_tmsi)</span><br><span style="color: hsl(120, 100%, 40%);">+ return hnb_tx_dt(hnb, gen_nas_tmsi_realloc_compl());</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM48_MT_MM_LOC_UPD_REJECT:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Received Location Update Reject\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM48_MT_MM_INFO:</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_nas_rx_mm_info(gh, len);</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_tx_iu_release_req(hnb);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM48_MT_MM_AUTH_REQ:</span><br><span style="color: hsl(120, 100%, 40%);">+ return hnb_nas_rx_auth_req(hnb, gh, len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("04.08 message type not handled by hnb-test: 0x%x\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ msg_type);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_nas_rx_dtap(struct hnb *hnb, void *data, int len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("got %d bytes: %s\n", len, osmo_hexdump(data, len));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ // nas_pdu == '05 08 12' ==> IMEI Identity request</span><br><span style="color: hsl(120, 100%, 40%);">+ // '05 04 0d' ==> LU reject</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm48_hdr *gh = data;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (len < sizeof(*gh)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("hnb_nas_rx_dtap(): NAS PDU is too short: %d. Ignoring.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ len);</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t pdisc = gsm48_hdr_pdisc(gh);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (pdisc) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case GSM48_PDISC_MM:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = hnb_nas_rx_mm(hnb, gh, len);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Error receiving MM message: %d\n", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("04.08 discriminator not handled by hnb-test: %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ pdisc);</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rx_secmode_cmd(struct hnb *hnb, long ip_alg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ printf(" :) Security Mode Command :)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ /* not caring about encryption yet, just pass 0 for No Encryption. */</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_tx_dt(hnb, ranap_new_msg_sec_mod_compl(ip_alg, 0));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rx_iu_release(struct hnb *hnb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_tx_iu_release_compl(hnb);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rx_paging(struct hnb *hnb, const char *imsi)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ printf(" :) Paging Request for %s :)\n", imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* TODO reply */</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int hnb_hnbap_rx(struct hnb *hnb, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ HNBAP_HNBAP_PDU_t _pdu, *pdu = &_pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+ asn_dec_rval_t dec_ret;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(pdu, 0, sizeof(*pdu));</span><br><span style="color: hsl(120, 100%, 40%);">+ dec_ret = aper_decode(NULL, &asn_DEF_HNBAP_HNBAP_PDU, (void **) &pdu,</span><br><span style="color: hsl(120, 100%, 40%);">+ msg->data, msgb_length(msg), 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (dec_ret.code != RC_OK) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_ERROR, "Error in ASN.1 decode\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pdu->present != HNBAP_HNBAP_PDU_PR_successfulOutcome) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Unexpected HNBAP message received\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (pdu->choice.successfulOutcome.procedureCode) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case HNBAP_ProcedureCode_id_HNBRegister:</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Get HNB id and send UE Register request */</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = hnb_rx_hnb_register_acc(hnb, &pdu->choice.successfulOutcome.value);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case HNBAP_ProcedureCode_id_UERegister:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = hnb_rx_ue_register_acc(hnb, &pdu->choice.successfulOutcome.value);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern void direct_transfer_nas_pdu_print(ANY_t *in);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int hnb_rua_rx(struct hnb *hnb, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ RUA_RUA_PDU_t _pdu, *pdu = &_pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+ asn_dec_rval_t dec_ret;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(pdu, 0, sizeof(*pdu));</span><br><span style="color: hsl(120, 100%, 40%);">+ dec_ret = aper_decode(NULL, &asn_DEF_RUA_RUA_PDU, (void **) &pdu,</span><br><span style="color: hsl(120, 100%, 40%);">+ msg->data, msgb_length(msg), 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (dec_ret.code != RC_OK) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_ERROR, "Error in ASN.1 decode\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (pdu->present) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case RUA_RUA_PDU_PR_successfulOutcome:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("RUA_RUA_PDU_PR_successfulOutcome\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case RUA_RUA_PDU_PR_initiatingMessage:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("RUA_RUA_PDU_PR_initiatingMessage\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case RUA_RUA_PDU_PR_NOTHING:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("RUA_RUA_PDU_PR_NOTHING\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case RUA_RUA_PDU_PR_unsuccessfulOutcome:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("RUA_RUA_PDU_PR_unsuccessfulOutcome\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Unexpected RUA message received\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (pdu->choice.successfulOutcome.procedureCode) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case RUA_ProcedureCode_id_ConnectionlessTransfer:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("RUA rx Connectionless Transfer\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_rua_cl_handle(hnb, &pdu->choice.successfulOutcome.value);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case RUA_ProcedureCode_id_Connect:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("RUA rx Connect\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case RUA_ProcedureCode_id_DirectTransfer:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("RUA rx DirectTransfer\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_rua_dt_handle(hnb, &pdu->choice.successfulOutcome.value);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case RUA_ProcedureCode_id_Disconnect:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("RUA rx Disconnect\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case RUA_ProcedureCode_id_ErrorIndication:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("RUA rx ErrorIndication\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case RUA_ProcedureCode_id_privateMessage:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("RUA rx privateMessage\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("RUA rx unknown message\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int hnb_read_cb(struct osmo_fd *fd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb *hnb = fd->data;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sctp_sndrcvinfo sinfo;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg = msgb_alloc(IUH_MSGB_SIZE, "Iuh rx");</span><br><span style="color: hsl(120, 100%, 40%);">+ int flags = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = sctp_recvmsg(fd->fd, msgb_data(msg), msgb_tailroom(msg),</span><br><span style="color: hsl(120, 100%, 40%);">+ NULL, NULL, &sinfo, &flags);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_ERROR, "Error during sctp_recvmsg()\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: clean up after disappeared HNB */</span><br><span style="color: hsl(120, 100%, 40%);">+ close(fd->fd);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fd_unregister(fd);</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (rc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_INFO, "Connection to HNB closed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ close(fd->fd);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fd_unregister(fd);</span><br><span style="color: hsl(120, 100%, 40%);">+ fd->fd = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_put(msg, rc);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (flags & MSG_NOTIFICATION) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_DEBUG, "Ignoring SCTP notification\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ sinfo.sinfo_ppid = ntohl(sinfo.sinfo_ppid);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (sinfo.sinfo_ppid) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case IUH_PPI_HNBAP:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("HNBAP message received\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = hnb_hnbap_rx(hnb, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case IUH_PPI_RUA:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("RUA message received\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = hnb_rua_rx(hnb, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case IUH_PPI_SABP:</span><br><span style="color: hsl(120, 100%, 40%);">+ case IUH_PPI_RNA:</span><br><span style="color: hsl(120, 100%, 40%);">+ case IUH_PPI_PUA:</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_ERROR, "Unimplemented SCTP PPID=%u received\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ sinfo.sinfo_ppid);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DMAIN, LOGL_ERROR, "Unknown SCTP PPID=%u received\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ sinfo.sinfo_ppid);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int hnb_write_cb(struct osmo_fd *fd, struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ /* struct hnb *ctx = fd->data; */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sctp_sndrcvinfo sinfo = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .sinfo_ppid = htonl(msgb_sctp_ppid(msg)),</span><br><span style="color: hsl(120, 100%, 40%);">+ .sinfo_stream = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Sending: %s\n", osmo_hexdump(msgb_data(msg), msgb_length(msg)));</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = sctp_send(fd->fd, msgb_data(msg), msgb_length(msg),</span><br><span style="color: hsl(120, 100%, 40%);">+ &sinfo, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* we don't need to msgb_free(), write_queue does this for us */</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void hnb_send_register_req(struct hnb *hnb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ HNBAP_HNBRegisterRequest_t request_out;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t lac, sac;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t rac;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t cid;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t plmn[] = {0x09, 0xf1, 0x99};</span><br><span style="color: hsl(120, 100%, 40%);">+ char identity[50] = "ATestHNB@";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ HNBAP_HNBRegisterRequestIEs_t request;</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&request, 0, sizeof(request));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ lac = 0xc0fe;</span><br><span style="color: hsl(120, 100%, 40%);">+ sac = 0xabab;</span><br><span style="color: hsl(120, 100%, 40%);">+ rac = 0x42;</span><br><span style="color: hsl(120, 100%, 40%);">+ cid = 0xadceaab;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ asn1_u16_to_str(&request.lac, &lac, lac);</span><br><span style="color: hsl(120, 100%, 40%);">+ asn1_u16_to_str(&request.sac, &sac, sac);</span><br><span style="color: hsl(120, 100%, 40%);">+ asn1_u8_to_str(&request.rac, &rac, rac);</span><br><span style="color: hsl(120, 100%, 40%);">+ asn1_u28_to_bitstring(&request.cellIdentity, &cid, cid);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ request.hnB_Identity.hNB_Identity_Info.buf = (uint8_t*) identity;</span><br><span style="color: hsl(120, 100%, 40%);">+ request.hnB_Identity.hNB_Identity_Info.size = strlen(identity);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ request.plmNidentity.buf = plmn;</span><br><span style="color: hsl(120, 100%, 40%);">+ request.plmNidentity.size = 3;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&request_out, 0, sizeof(request_out));</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = hnbap_encode_hnbregisterrequesties(&request_out, &request);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Could not encode HNB register request IEs\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = hnbap_generate_initiating_message(HNBAP_ProcedureCode_id_HNBRegister,</span><br><span style="color: hsl(120, 100%, 40%);">+ HNBAP_Criticality_reject,</span><br><span style="color: hsl(120, 100%, 40%);">+ &asn_DEF_HNBAP_HNBRegisterRequest,</span><br><span style="color: hsl(120, 100%, 40%);">+ &request_out);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_sctp_ppid(msg) = IUH_PPI_HNBAP;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_wqueue_enqueue(&hnb->wqueue, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void hnb_send_deregister_req(struct hnb *hnb)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ HNBAP_HNBDe_RegisterIEs_t request;</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&request, 0, sizeof(request));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ request.cause.present = HNBAP_Cause_PR_misc;</span><br><span style="color: hsl(120, 100%, 40%);">+ request.cause.choice.misc = HNBAP_CauseMisc_o_and_m_intervention;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ HNBAP_HNBDe_Register_t request_out;</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&request_out, 0, sizeof(request_out));</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = hnbap_encode_hnbde_registeries(&request_out, &request);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Could not encode HNB deregister request IEs\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = hnbap_generate_initiating_message(HNBAP_ProcedureCode_id_HNBDe_Register,</span><br><span style="color: hsl(120, 100%, 40%);">+ HNBAP_Criticality_reject,</span><br><span style="color: hsl(120, 100%, 40%);">+ &asn_DEF_HNBAP_HNBDe_Register,</span><br><span style="color: hsl(120, 100%, 40%);">+ &request_out);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_sctp_ppid(msg) = IUH_PPI_HNBAP;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_wqueue_enqueue(&hnb->wqueue, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct vty_app_info vty_info = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "OsmohNodeB",</span><br><span style="color: hsl(120, 100%, 40%);">+ .version = "0",</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int sctp_sock_init(int fd)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sctp_event_subscribe event;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* subscribe for all events */</span><br><span style="color: hsl(120, 100%, 40%);">+ memset((uint8_t *)&event, 1, sizeof(event));</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS,</span><br><span style="color: hsl(120, 100%, 40%);">+ &event, sizeof(event));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define HNBAP_STR "HNBAP related commands\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define HNB_STR "HomeNodeB commands\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define UE_STR "User Equipment commands\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define RANAP_STR "RANAP related commands\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define CSPS_STR "Circuit Switched\n" "Packet Switched\n"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(hnb_register, hnb_register_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "hnbap hnb register", HNBAP_STR HNB_STR "Send HNB-REGISTER REQUEST")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_send_register_req(&g_hnb);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(hnb_deregister, hnb_deregister_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "hnbap hnb deregister", HNBAP_STR HNB_STR "Send HNB-DEREGISTER REQUEST")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_send_deregister_req(&g_hnb);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(ue_register, ue_register_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "hnbap ue register IMSI", HNBAP_STR UE_STR "Send UE-REGISTER REQUEST")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_ue_register_tx(&g_hnb, argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(asn_dbg, asn_dbg_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "asn-debug (1|0)", "Enable or disable libasn1c debugging")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ asn_debug = atoi(argv[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(ranap_reset, ranap_reset_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "ranap reset (cs|ps)", RANAP_STR "Send RANAP RESET\n" CSPS_STR)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int is_ps = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg, *rua;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ RANAP_Cause_t cause = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .present = RANAP_Cause_PR_transmissionNetwork,</span><br><span style="color: hsl(120, 100%, 40%);">+ .choice.transmissionNetwork = RANAP_CauseTransmissionNetwork_signalling_transport_resource_failure,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcmp(argv[0], "ps"))</span><br><span style="color: hsl(120, 100%, 40%);">+ is_ps = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = ranap_new_msg_reset(is_ps, &cause);</span><br><span style="color: hsl(120, 100%, 40%);">+ rua = rua_new_udt(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ //msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_wqueue_enqueue(&g_hnb.wqueue, rua);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum my_vty_nodes {</span><br><span style="color: hsl(120, 100%, 40%);">+ CHAN_NODE = _LAST_OSMOVTY_NODE,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct cmd_node chan_node = {</span><br><span style="color: hsl(120, 100%, 40%);">+ CHAN_NODE,</span><br><span style="color: hsl(120, 100%, 40%);">+ "%s(chan)> ",</span><br><span style="color: hsl(120, 100%, 40%);">+ 1,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct msgb *gen_initue_lu(int is_ps, uint32_t conn_id, const char *imsi)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t lu[] = { GSM48_PDISC_MM, GSM48_MT_MM_LOC_UPD_REQUEST,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x70, 0x62, 0xf2, 0x30, 0xff, 0xf3, 0x57,</span><br><span style="color: hsl(120, 100%, 40%);">+ /* len, IMSI/type, IMSI-------------------------------- */</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x08, 0x29, 0x26, 0x24, 0x10, 0x32, 0x54, 0x76, 0x98,</span><br><span style="color: hsl(120, 100%, 40%);">+ 0x33, 0x03, 0x57, 0x18 , 0xb2 };</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t plmn_id[] = { 0x09, 0x01, 0x99 };</span><br><span style="color: hsl(120, 100%, 40%);">+ RANAP_GlobalRNC_ID_t rnc_id = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .rNC_ID = 23,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pLMNidentity.buf = plmn_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ .pLMNidentity.size = sizeof(plmn_id),</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: patch imsi */</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Note: the Mobile Identitiy IE's IMSI data has the identity type and</span><br><span style="color: hsl(120, 100%, 40%);">+ * an even/odd indicator bit encoded in the first octet. So the first</span><br><span style="color: hsl(120, 100%, 40%);">+ * octet looks like this:</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * 8 7 6 5 | 4 | 3 2 1</span><br><span style="color: hsl(120, 100%, 40%);">+ * IMSI-digit | even/odd | type</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * followed by the remaining IMSI digits.</span><br><span style="color: hsl(120, 100%, 40%);">+ * If digit count is even (bit 4 == 0), that first high-nibble is 0xf.</span><br><span style="color: hsl(120, 100%, 40%);">+ * (derived from Iu pcap Location Update Request msg and TS 25.413)</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * TODO I'm only 90% sure about this</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return ranap_new_msg_initial_ue(conn_id, is_ps, &rnc_id, lu, sizeof(lu));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(chan, chan_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "channel (cs|ps) lu imsi IMSI",</span><br><span style="color: hsl(120, 100%, 40%);">+ "Open a new Signalling Connection\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "To Circuit-Switched CN\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "To Packet-Switched CN\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "Performing a Location Update\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ )</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_chan *chan;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg, *rua;</span><br><span style="color: hsl(120, 100%, 40%);">+ static uint16_t conn_id = 42;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ chan = talloc_zero(tall_hnb_ctx, struct hnb_chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcmp(argv[0], "ps"))</span><br><span style="color: hsl(120, 100%, 40%);">+ chan->is_ps = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ chan->imsi = talloc_strdup(chan, argv[1]);</span><br><span style="color: hsl(120, 100%, 40%);">+ chan->conn_id = conn_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ conn_id++;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = gen_initue_lu(chan->is_ps, chan->conn_id, chan->imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+ rua = rua_new_conn(chan->is_ps, chan->conn_id, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_wqueue_enqueue(&g_hnb.wqueue, rua);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ vty->index = chan;</span><br><span style="color: hsl(120, 100%, 40%);">+ vty->node = CHAN_NODE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!chan->is_ps)</span><br><span style="color: hsl(120, 100%, 40%);">+ g_hnb.cs.chan = chan;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void hnb_vty_init(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element_ve(&asn_dbg_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element_ve(&hnb_register_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element_ve(&hnb_deregister_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element_ve(&ue_register_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element_ve(&ranap_reset_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element_ve(&chan_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ install_node(&chan_node, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void handle_options(int argc, char **argv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ while (1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ int idx = 0, c;</span><br><span style="color: hsl(120, 100%, 40%);">+ static const struct option long_options[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ { "ues", 1, 0, 'u' },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "gw-addr", 1, 0, 'g' },</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0, 0, 0, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ c = getopt_long(argc, argv, "u:g:", long_options, &idx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (c == -1)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (c) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case 'u':</span><br><span style="color: hsl(120, 100%, 40%);">+ g_hnb.ues = atoi(optarg);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case 'g':</span><br><span style="color: hsl(120, 100%, 40%);">+ g_hnb.gw_addr = optarg;</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ tall_hnb_ctx = talloc_named_const(NULL, 0, "hnb_context");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_talloc_ctx_init(tall_hnb_ctx, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_asn1_ctx = talloc_named_const(tall_hnb_ctx, 0, "asn1_context");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_init_logging2(tall_hnb_ctx, &hnb_log_info);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ranap_set_log_area(DRANAP);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);</span><br><span style="color: hsl(120, 100%, 40%);">+ log_set_use_color(osmo_stderr_target, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ log_set_print_category(osmo_stderr_target, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ log_set_print_category_hex(osmo_stderr_target, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_init(&vty_info);</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_vty_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = telnet_init_dynif(NULL, NULL, vty_get_bind_addr(), 2324);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ perror("Error binding VTY port");</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(1);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ handle_options(argc, argv);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_wqueue_init(&g_hnb.wqueue, 16);</span><br><span style="color: hsl(120, 100%, 40%);">+ g_hnb.wqueue.bfd.data = &g_hnb;</span><br><span style="color: hsl(120, 100%, 40%);">+ g_hnb.wqueue.read_cb = hnb_read_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+ g_hnb.wqueue.write_cb = hnb_write_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_sock_init_ofd(&g_hnb.wqueue.bfd, AF_INET, SOCK_STREAM,</span><br><span style="color: hsl(120, 100%, 40%);">+ IPPROTO_SCTP, g_hnb.gw_addr,</span><br><span style="color: hsl(120, 100%, 40%);">+ g_hnb.gw_port, OSMO_SOCK_F_CONNECT);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ perror("Error connecting to Iuh port");</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(1);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ sctp_sock_init(g_hnb.wqueue.bfd.fd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#if 0</span><br><span style="color: hsl(120, 100%, 40%);">+ /* some hard-coded message generation. Doesn't make sense from</span><br><span style="color: hsl(120, 100%, 40%);">+ * a protocol point of view but enables to look at the encoded</span><br><span style="color: hsl(120, 100%, 40%);">+ * results in wireshark for manual verification */</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct msgb *msg, *rua;</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint8_t nas[] = { 0, 1, 2, 3 };</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint8_t ik[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = ranap_new_msg_dt(0, nas, sizeof(nas));</span><br><span style="color: hsl(120, 100%, 40%);">+ rua = rua_new_udt(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_wqueue_enqueue(&g_hnb.wqueue, rua);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = ranap_new_msg_sec_mod_cmd(ik, ik, RANAP_KeyStatus_new);</span><br><span style="color: hsl(120, 100%, 40%);">+ rua = rua_new_udt(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_wqueue_enqueue(&g_hnb.wqueue, rua);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = ranap_new_msg_iu_rel_cmd()</span><br><span style="color: hsl(120, 100%, 40%);">+ rua = rua_new_udt(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_wqueue_enqueue(&g_hnb.wqueue, rua);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = ranap_new_msg_paging_cmd("901990123456789", NULL, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ rua = rua_new_udt(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_wqueue_enqueue(&g_hnb.wqueue, rua);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = ranap_new_msg_rab_assign_voice(1, 0x01020304, 0x1020);</span><br><span style="color: hsl(120, 100%, 40%);">+ rua = rua_new_udt(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_wqueue_enqueue(&g_hnb.wqueue, rua);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = ranap_new_msg_rab_assign_data(2, 0x01020304, 0x11223344);</span><br><span style="color: hsl(120, 100%, 40%);">+ rua = rua_new_udt(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_wqueue_enqueue(&g_hnb.wqueue, rua);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while (1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_select_main(0);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(3);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* not reached */</span><br><span style="color: hsl(120, 100%, 40%);">+ exit(0);</span><br><span> }</span><br><span>diff --git a/src/osmo-hnodeb/ranap.c b/src/osmo-hnodeb/ranap.c</span><br><span>new file mode 100644</span><br><span>index 0000000..a6a92cc</span><br><span>--- /dev/null</span><br><span>+++ b/src/osmo-hnodeb/ranap.c</span><br><span>@@ -0,0 +1,107 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2015 by Daniel Willmann <dwillmann@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Pau Espin Pedrol <pespin@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU Affero General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program. If not, see <http://www.gnu.org/lienses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ranap/ranap_common_cn.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ranap/ranap_ies_defs.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ranap/iu_helpers.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnodeb/ranap.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *printstr(OCTET_STRING_t *s)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return osmo_hexdump((const unsigned char*)s->buf, s->size);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define PP(octet_string_t) \</span><br><span style="color: hsl(120, 100%, 40%);">+ printf(#octet_string_t " = %s\n",\</span><br><span style="color: hsl(120, 100%, 40%);">+ printstr(&octet_string_t))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rua_dt_handle_ranap(struct hnb *hnb,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ranap_message_s *ranap_msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int len;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *data;</span><br><span style="color: hsl(120, 100%, 40%);">+ RANAP_PermittedIntegrityProtectionAlgorithms_t *algs;</span><br><span style="color: hsl(120, 100%, 40%);">+ RANAP_IntegrityProtectionAlgorithm_t *first_alg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("rx ranap_msg->procedureCode %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ ranap_msg->procedureCode);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (ranap_msg->procedureCode) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case RANAP_ProcedureCode_id_DirectTransfer:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("rx DirectTransfer: presence = %hx\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ ranap_msg->msg.directTransferIEs.presenceMask);</span><br><span style="color: hsl(120, 100%, 40%);">+ PP(ranap_msg->msg.directTransferIEs.nas_pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ len = ranap_msg->msg.directTransferIEs.nas_pdu.size;</span><br><span style="color: hsl(120, 100%, 40%);">+ data = ranap_msg->msg.directTransferIEs.nas_pdu.buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_nas_rx_dtap(hnb, data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case RANAP_ProcedureCode_id_SecurityModeControl:</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("rx SecurityModeControl: presence = %hx\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ ranap_msg->msg.securityModeCommandIEs.presenceMask);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Just pick the first available IP alg, don't care about</span><br><span style="color: hsl(120, 100%, 40%);">+ * encryption (yet?) */</span><br><span style="color: hsl(120, 100%, 40%);">+ algs = &ranap_msg->msg.securityModeCommandIEs.integrityProtectionInformation.permittedAlgorithms;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (algs->list.count < 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Security Mode Command: No permitted algorithms.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ first_alg = *algs->list.array;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_rx_secmode_cmd(hnb, *first_alg);</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case RANAP_ProcedureCode_id_Iu_Release:</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_rx_iu_release(hnb);</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rua_cl_handle_ranap(struct hnb *hnb,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ranap_message_s *ranap_msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char imsi[16];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("rx ranap_msg->procedureCode %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ ranap_msg->procedureCode);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (ranap_msg->procedureCode) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case RANAP_ProcedureCode_id_Paging:</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ranap_msg->msg.pagingIEs.permanentNAS_UE_ID.present == RANAP_PermanentNAS_UE_ID_PR_iMSI) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ranap_bcd_decode(imsi, sizeof(imsi),</span><br><span style="color: hsl(120, 100%, 40%);">+ ranap_msg->msg.pagingIEs.permanentNAS_UE_ID.choice.iMSI.buf,</span><br><span style="color: hsl(120, 100%, 40%);">+ ranap_msg->msg.pagingIEs.permanentNAS_UE_ID.choice.iMSI.size);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else imsi[0] = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("rx Paging: presence=%hx domain=%ld IMSI=%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ ranap_msg->msg.pagingIEs.presenceMask,</span><br><span style="color: hsl(120, 100%, 40%);">+ ranap_msg->msg.pagingIEs.cN_DomainIndicator,</span><br><span style="color: hsl(120, 100%, 40%);">+ imsi</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_rx_paging(hnb, imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/osmo-hnodeb/rua.c b/src/osmo-hnodeb/rua.c</span><br><span>new file mode 100644</span><br><span>index 0000000..3db9de7</span><br><span>--- /dev/null</span><br><span>+++ b/src/osmo-hnodeb/rua.c</span><br><span>@@ -0,0 +1,61 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2015 by Daniel Willmann <dwillmann@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Pau Espin Pedrol <pespin@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU Affero General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program. If not, see <http://www.gnu.org/lienses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#include <asn1c/ANY.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/rua/rua_ies_defs.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/ranap/ranap_common_cn.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnodeb/rua.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnodeb/ranap.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rua_dt_handle(struct hnb *hnb, ANY_t *in)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ RUA_DirectTransferIEs_t ies;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = rua_decode_directtransferies(&ies, in);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("failed to decode RUA DT IEs\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = ranap_cn_rx_co(hnb_rua_dt_handle_ranap, hnb, ies.ranaP_Message.buf, ies.ranaP_Message.size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: what to do with the asn1c-allocated memory */</span><br><span style="color: hsl(120, 100%, 40%);">+ rua_free_directtransferies(&ies);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void hnb_rua_cl_handle(struct hnb *hnb, ANY_t *in)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ RUA_ConnectionlessTransferIEs_t ies;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = rua_decode_connectionlesstransferies(&ies, in);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("failed to decode RUA CL IEs\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = ranap_cn_rx_cl(hnb_rua_cl_handle_ranap, hnb, ies.ranaP_Message.buf, ies.ranaP_Message.size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: what to do with the asn1c-allocated memory */</span><br><span style="color: hsl(120, 100%, 40%);">+ rua_free_connectionlesstransferies(&ies);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-hnodeb/+/25995">change 25995</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-hnodeb/+/25995"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-hnodeb </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I36fd4aa5d39222371bd36e9f540b91e36a26de43 </div>
<div style="display:none"> Gerrit-Change-Number: 25995 </div>
<div style="display:none"> Gerrit-PatchSet: 6 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>