<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>