<p>pespin <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-hnodeb/+/26502">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
laforge: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">First implementation of the LLSK audio SAPI<br><br>This first version can send and receive regular RTP, but does not talk IuUP.<br>Support for IuUP will be added in a future patch. This way we can<br>already test the whole LLSK<->RTP path.<br><br>Change-Id: I9909a7c054ddaabb1bb63d7d06331cc79f642b5d<br>---<br>M configure.ac<br>M include/osmocom/hnodeb/Makefile.am<br>M include/osmocom/hnodeb/hnb_prim.h<br>M include/osmocom/hnodeb/hnodeb.h<br>M include/osmocom/hnodeb/llsk.h<br>A include/osmocom/hnodeb/rtp.h<br>M src/osmo-hnodeb/Makefile.am<br>M src/osmo-hnodeb/debug.c<br>M src/osmo-hnodeb/hnb.c<br>M src/osmo-hnodeb/llsk.c<br>A src/osmo-hnodeb/llsk_audio.c<br>M src/osmo-hnodeb/main.c<br>A src/osmo-hnodeb/rtp.c<br>13 files changed, 732 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 8453bc4..e96a6a1 100644</span><br><span>--- a/configure.ac</span><br><span>+++ b/configure.ac</span><br><span>@@ -61,6 +61,7 @@</span><br><span> PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.6.0)</span><br><span> PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.6.0)</span><br><span> PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.2.0)</span><br><span style="color: hsl(120, 100%, 40%);">+PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.2.0)</span><br><span> PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.1.0)</span><br><span> PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.5.0)</span><br><span> PKG_CHECK_MODULES(LIBOSMORUA, libosmo-rua >= 0.8.0)</span><br><span>diff --git a/include/osmocom/hnodeb/Makefile.am b/include/osmocom/hnodeb/Makefile.am</span><br><span>index 62af5bb..dcb3868 100644</span><br><span>--- a/include/osmocom/hnodeb/Makefile.am</span><br><span>+++ b/include/osmocom/hnodeb/Makefile.am</span><br><span>@@ -6,6 +6,7 @@</span><br><span> iuh.h \</span><br><span> llsk.h \</span><br><span> ranap.h \</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp.h \</span><br><span> rua.h \</span><br><span> vty.h \</span><br><span> $(NULL)</span><br><span>diff --git a/include/osmocom/hnodeb/hnb_prim.h b/include/osmocom/hnodeb/hnb_prim.h</span><br><span>index 6d597c4..dab00c9 100644</span><br><span>--- a/include/osmocom/hnodeb/hnb_prim.h</span><br><span>+++ b/include/osmocom/hnodeb/hnb_prim.h</span><br><span>@@ -40,6 +40,16 @@</span><br><span> #define HNB_PRIM_SAPI_GTP 2</span><br><span> #define HNB_PRIM_SAPI_AUDIO 3</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+enum u_addr_type {</span><br><span style="color: hsl(120, 100%, 40%);">+ HNB_PRIM_ADDR_TYPE_UNSPEC,</span><br><span style="color: hsl(120, 100%, 40%);">+ HNB_PRIM_ADDR_TYPE_IPV4,</span><br><span style="color: hsl(120, 100%, 40%);">+ HNB_PRIM_ADDR_TYPE_IPV6</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+union u_addr {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct in_addr v4;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct in6_addr v6;</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! \brief HNB_IUH primitives */</span><br><span> enum hnb_iuh_prim_type {</span><br><span> HNB_IUH_PRIM_CONFIGURE,</span><br><span>@@ -163,3 +173,62 @@</span><br><span> struct hnb_iuh_unitdata_ind_param unitdata_ind;</span><br><span> } u;</span><br><span> } __attribute__ ((packed));</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%);">+ * AUDIO</span><br><span style="color: hsl(120, 100%, 40%);">+ ***************************/</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief HNB_AUDIO primitives */</span><br><span style="color: hsl(120, 100%, 40%);">+enum hnb_audio_prim_type {</span><br><span style="color: hsl(120, 100%, 40%);">+ HNB_AUDIO_PRIM_CONN_ESTABLISH,</span><br><span style="color: hsl(120, 100%, 40%);">+ HNB_AUDIO_PRIM_CONN_RELEASE,</span><br><span style="color: hsl(120, 100%, 40%);">+ HNB_AUDIO_PRIM_CONN_DATA,</span><br><span style="color: hsl(120, 100%, 40%);">+ _HNB_AUDIO_PRIM_MAX</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_AUDIO_PRIM_CONN_ESTABLISH, UL */</span><br><span style="color: hsl(120, 100%, 40%);">+struct hnb_audio_conn_establish_req_param {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t context_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t remote_rtp_port;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t spare1;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t remote_rtp_address_type; /* enum u_addr_type */</span><br><span style="color: hsl(120, 100%, 40%);">+ union u_addr remote_rtp_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* HNB_AUDIO_PRIM_CONN_ESTABLISH, DL */</span><br><span style="color: hsl(120, 100%, 40%);">+struct hnb_audio_conn_establish_cnf_param {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t context_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t local_rtp_port;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t error_code; /* 0 = success, !0 = failure */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t local_rtp_address_type; /* enum u_addr_type */</span><br><span style="color: hsl(120, 100%, 40%);">+ union u_addr local_rtp_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* HNB_AUDIO_PRIM_CONN_RELEASE, UL */</span><br><span style="color: hsl(120, 100%, 40%);">+struct hnb_audio_conn_release_req_param {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t context_id;</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* HNB_AUDIO_PRIM_CONN_DATA, UL */</span><br><span style="color: hsl(120, 100%, 40%);">+struct hnb_audio_conn_data_req_param {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t context_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t data_len; /* RTP payload length in bytes */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t data[0]; /* RTP payload (aka IP packet) */</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* HNB_AUDIO_PRIM_CONN_DATA, DL */</span><br><span style="color: hsl(120, 100%, 40%);">+struct hnb_audio_conn_data_ind_param {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t context_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t data_len; /* RTP payload length in bytes */</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t data[0]; /* RTP payload (aka IP packet) */</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct hnb_audio_prim {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_prim_hdr hdr;</span><br><span style="color: hsl(120, 100%, 40%);">+ union {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_audio_conn_establish_req_param conn_establish_req;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_audio_conn_establish_cnf_param conn_establish_cnf;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_audio_conn_release_req_param conn_release_req;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_audio_conn_data_req_param conn_data_req;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_audio_conn_data_ind_param conn_data_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+ } u;</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__ ((packed));</span><br><span>diff --git a/include/osmocom/hnodeb/hnodeb.h b/include/osmocom/hnodeb/hnodeb.h</span><br><span>index fd7d1e9..15244c4 100644</span><br><span>--- a/include/osmocom/hnodeb/hnodeb.h</span><br><span>+++ b/include/osmocom/hnodeb/hnodeb.h</span><br><span>@@ -21,11 +21,13 @@</span><br><span> </span><br><span> #include <stdint.h></span><br><span> #include <stdbool.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <inttypes.h></span><br><span> </span><br><span> #include <asn1c/asn1helpers.h></span><br><span> </span><br><span> #include <osmocom/core/select.h></span><br><span> #include <osmocom/core/timer.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/socket.h></span><br><span> #include <osmocom/core/linuxlist.h></span><br><span> #include <osmocom/core/write_queue.h></span><br><span> #include <osmocom/core/logging.h></span><br><span>@@ -42,6 +44,7 @@</span><br><span> DRANAP,</span><br><span> DSCTP,</span><br><span> DLLSK,</span><br><span style="color: hsl(120, 100%, 40%);">+ DRTP,</span><br><span> };</span><br><span> extern const struct log_info hnb_log_info;</span><br><span> </span><br><span>@@ -55,6 +58,9 @@</span><br><span> struct hnb_ue_cs_ctx {</span><br><span> bool active; /* Is this chan in use? */</span><br><span> bool conn_est_cnf_pending; /* Did we send CONN_ESTABLISH_CNF to lower layers? */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_rtp_socket *socket;</span><br><span style="color: hsl(120, 100%, 40%);">+ } rtp;</span><br><span> } conn_cs;</span><br><span> struct hnb_ue_ps_ctx {</span><br><span> bool active; /* Is this chan in use? */</span><br><span>@@ -86,6 +92,17 @@</span><br><span> uint8_t llsk_valid_sapi_mask;</span><br><span> struct osmo_timer_list llsk_defer_configure_ind_timer;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ struct {</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int jitter_buf_ms;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool jitter_adaptive;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t port_range_start;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t port_range_end;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t port_range_next;</span><br><span style="color: hsl(120, 100%, 40%);">+ int ip_dscp;</span><br><span style="color: hsl(120, 100%, 40%);">+ int priority;</span><br><span style="color: hsl(120, 100%, 40%);">+ } rtp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> uint16_t rnc_id;</span><br><span> bool registered; /* Set to true once HnbRegisterAccept was received from Iuh. rnc_id is valid iif registered==true */</span><br><span> </span><br><span>@@ -104,3 +121,5 @@</span><br><span> </span><br><span> extern void *tall_hnb_ctx;</span><br><span> extern struct hnb *g_hnb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define LOGUE(ue, ss, lvl, fmt, args...) LOGP(ss, lvl, "UE(%" PRIu32 ") " fmt, (ue)->conn_id, ## args)</span><br><span>diff --git a/include/osmocom/hnodeb/llsk.h b/include/osmocom/hnodeb/llsk.h</span><br><span>index ab39439..0636a5f 100644</span><br><span>--- a/include/osmocom/hnodeb/llsk.h</span><br><span>+++ b/include/osmocom/hnodeb/llsk.h</span><br><span>@@ -22,15 +22,22 @@</span><br><span> #include <stdint.h></span><br><span> </span><br><span> #include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/socket.h></span><br><span> #include <osmocom/netif/prim.h></span><br><span> #include <osmocom/hnodeb/hnb_prim.h></span><br><span> </span><br><span> struct hnb;</span><br><span style="color: hsl(120, 100%, 40%);">+struct hnb_ue;</span><br><span> </span><br><span> int hnb_llsk_alloc(struct hnb *hnb);</span><br><span> bool hnb_llsk_connected(const struct hnb *hnb);</span><br><span> bool hnb_llsk_can_be_configured(struct hnb *hnb);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int ll_addr_type2af(enum u_addr_type t);</span><br><span style="color: hsl(120, 100%, 40%);">+int ll_addr2osa(enum u_addr_type t, const union u_addr *uaddr, uint16_t port, struct osmo_sockaddr *osa);</span><br><span style="color: hsl(120, 100%, 40%);">+enum u_addr_type osa2_ll_addr(const struct osmo_sockaddr *osa, union u_addr *uaddr, uint16_t *port);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> </span><br><span> extern const struct value_string hnb_iuh_prim_type_names[];</span><br><span> int llsk_rx_iuh(struct hnb *hnb, struct osmo_prim_hdr *oph);</span><br><span>@@ -42,3 +49,8 @@</span><br><span> const uint8_t *data,</span><br><span> uint32_t data_len);</span><br><span> struct hnb_iuh_prim *hnb_iuh_makeprim_unitdata_ind(const uint8_t *data, uint32_t data_len);</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 const struct value_string hnb_audio_prim_type_names[];</span><br><span style="color: hsl(120, 100%, 40%);">+int llsk_rx_audio(struct hnb *hnb, struct osmo_prim_hdr *oph);</span><br><span style="color: hsl(120, 100%, 40%);">+int llsk_audio_tx_conn_data_ind(struct hnb_ue *ue, const uint8_t *payload, uint32_t len);</span><br><span>diff --git a/include/osmocom/hnodeb/rtp.h b/include/osmocom/hnodeb/rtp.h</span><br><span>new file mode 100644</span><br><span>index 0000000..01ec1c4</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/hnodeb/rtp.h</span><br><span>@@ -0,0 +1,27 @@</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 <osmocom/core/socket.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%);">+struct hnb_ue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int hnb_ue_voicecall_setup(struct hnb_ue *ue, const struct osmo_sockaddr *rem_addr, struct osmo_sockaddr *loc_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+int hnb_ue_voicecall_release(struct hnb_ue *ue);</span><br><span>diff --git a/src/osmo-hnodeb/Makefile.am b/src/osmo-hnodeb/Makefile.am</span><br><span>index b6d2d49..4182814 100644</span><br><span>--- a/src/osmo-hnodeb/Makefile.am</span><br><span>+++ b/src/osmo-hnodeb/Makefile.am</span><br><span>@@ -14,6 +14,7 @@</span><br><span> $(LIBOSMONETIF_CFLAGS) \</span><br><span> $(COVERAGE_CFLAGS) \</span><br><span> $(LIBOSMOABIS_CFLAGS) \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(LIBOSMOTRAU_CFLAGS) \</span><br><span> $(LIBOSMOSIGTRAN_CFLAGS) \</span><br><span> $(LIBOSMORUA_CFLAGS) \</span><br><span> $(LIBOSMORANAP_CFLAGS) \</span><br><span>@@ -36,8 +37,10 @@</span><br><span> hnb_shutdown_fsm.c \</span><br><span> iuh.c \</span><br><span> llsk.c \</span><br><span style="color: hsl(120, 100%, 40%);">+ llsk_audio.c \</span><br><span> llsk_iuh.c \</span><br><span> ranap.c \</span><br><span style="color: hsl(120, 100%, 40%);">+ rtp.c \</span><br><span> rua.c \</span><br><span> vty.c \</span><br><span> $(NULL)</span><br><span>@@ -51,6 +54,7 @@</span><br><span> $(LIBOSMONETIF_LIBS) \</span><br><span> $(COVERAGE_LDFLAGS) \</span><br><span> $(LIBOSMOABIS_LIBS) \</span><br><span style="color: hsl(120, 100%, 40%);">+ $(LIBOSMOTRAU_LIBS) \</span><br><span> $(LIBOSMOSIGTRAN_LIBS) \</span><br><span> $(LIBOSMORUA_LIBS) \</span><br><span> $(LIBOSMORANAP_LIBS) \</span><br><span>diff --git a/src/osmo-hnodeb/debug.c b/src/osmo-hnodeb/debug.c</span><br><span>index f34851b..5d0dabd 100644</span><br><span>--- a/src/osmo-hnodeb/debug.c</span><br><span>+++ b/src/osmo-hnodeb/debug.c</span><br><span>@@ -52,6 +52,11 @@</span><br><span> .color = "\033[1;31m",</span><br><span> .description = "Lower Layer Unix Domain Socket",</span><br><span> },</span><br><span style="color: hsl(120, 100%, 40%);">+ [DRTP] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ .name = "DRTP", .loglevel = LOGL_NOTICE, .enabled = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ .color = "\033[1;32m",</span><br><span style="color: hsl(120, 100%, 40%);">+ .description = "RTP Core Network side",</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span> };</span><br><span> </span><br><span> const struct log_info hnb_log_info = {</span><br><span>diff --git a/src/osmo-hnodeb/hnb.c b/src/osmo-hnodeb/hnb.c</span><br><span>index 1ac2efc..4c949f5 100644</span><br><span>--- a/src/osmo-hnodeb/hnb.c</span><br><span>+++ b/src/osmo-hnodeb/hnb.c</span><br><span>@@ -20,15 +20,20 @@</span><br><span> </span><br><span> #include "config.h"</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include <osmocom/core/socket.h></span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/netif/stream.h></span><br><span> #include <osmocom/netif/prim.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/trau/osmo_ortp.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include <osmocom/hnodeb/hnodeb.h></span><br><span> #include <osmocom/hnodeb/iuh.h></span><br><span> #include <osmocom/hnodeb/hnb_shutdown_fsm.h></span><br><span> #include <osmocom/hnodeb/hnb_prim.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnodeb/rtp.h></span><br><span> </span><br><span> </span><br><span> struct hnb *hnb_alloc(void *tall_ctx)</span><br><span>@@ -46,6 +51,14 @@</span><br><span> .mcc = 1,</span><br><span> .mnc = 1,</span><br><span> };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->rtp.jitter_adaptive = false;</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->rtp.port_range_start = 16384;</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->rtp.port_range_end = 17407;</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->rtp.port_range_next = hnb->rtp.port_range_start;</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->rtp.ip_dscp = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->rtp.priority = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> hnb->shutdown_fi = osmo_fsm_inst_alloc(&hnb_shutdown_fsm, hnb, hnb,</span><br><span> LOGL_INFO, NULL);</span><br><span> </span><br><span>@@ -94,16 +107,20 @@</span><br><span> </span><br><span> void hnb_ue_free(struct hnb_ue *ue)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_ue_reset_chan(ue, true);</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_ue_reset_chan(ue, false);</span><br><span> llist_del(&ue->list);</span><br><span> talloc_free(ue);</span><br><span> }</span><br><span> </span><br><span> void hnb_ue_reset_chan(struct hnb_ue *ue, bool is_ps)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- if (is_ps)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (is_ps) {</span><br><span> ue->conn_ps = (struct hnb_ue_ps_ctx){0};</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_ue_voicecall_release(ue);</span><br><span> ue->conn_cs = (struct hnb_ue_cs_ctx){0};</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span> }</span><br><span> </span><br><span> struct hnb_ue *hnb_find_ue_by_id(const struct hnb *hnb, uint32_t conn_id)</span><br><span>diff --git a/src/osmo-hnodeb/llsk.c b/src/osmo-hnodeb/llsk.c</span><br><span>index 5f0f9dc..8c93318 100644</span><br><span>--- a/src/osmo-hnodeb/llsk.c</span><br><span>+++ b/src/osmo-hnodeb/llsk.c</span><br><span>@@ -18,6 +18,9 @@</span><br><span> */</span><br><span> </span><br><span> #include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/socket.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <inttypes.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arpa/inet.h></span><br><span> </span><br><span> #include <osmocom/core/prim.h></span><br><span> #include <osmocom/core/logging.h></span><br><span>@@ -27,6 +30,58 @@</span><br><span> #include <osmocom/hnodeb/hnb_prim.h></span><br><span> #include <osmocom/hnodeb/hnb_shutdown_fsm.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int ll_addr_type2af(enum u_addr_type t)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (t) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case HNB_PRIM_ADDR_TYPE_IPV4:</span><br><span style="color: hsl(120, 100%, 40%);">+ return AF_INET;</span><br><span style="color: hsl(120, 100%, 40%);">+ case HNB_PRIM_ADDR_TYPE_IPV6:</span><br><span style="color: hsl(120, 100%, 40%);">+ return AF_INET6;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_ERROR, "Rx Unknwon address type %u\n", (unsigned)t);</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int ll_addr2osa(enum u_addr_type t, const union u_addr *uaddr, uint16_t port, struct osmo_sockaddr *osa)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int af = ll_addr_type2af(t);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ osa->u.sa.sa_family = af;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (af) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case AF_INET6:</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(&osa->u.sin6.sin6_addr, &uaddr->v6, sizeof(osa->u.sin6.sin6_addr));</span><br><span style="color: hsl(120, 100%, 40%);">+ osa->u.sin6.sin6_port = htons(port);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case AF_INET:</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(&osa->u.sin.sin_addr, &uaddr->v4, sizeof(osa->u.sin.sin_addr));</span><br><span style="color: hsl(120, 100%, 40%);">+ osa->u.sin.sin_port = htons(port);</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%);">+ return -1;</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%);">+enum u_addr_type osa2_ll_addr(const struct osmo_sockaddr *osa, union u_addr *uaddr, uint16_t *port)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (osa->u.sa.sa_family) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case AF_INET6:</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(&uaddr->v6, &osa->u.sin6.sin6_addr, sizeof(osa->u.sin6.sin6_addr));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (port)</span><br><span style="color: hsl(120, 100%, 40%);">+ *port = ntohs(osa->u.sin6.sin6_port);</span><br><span style="color: hsl(120, 100%, 40%);">+ return HNB_PRIM_ADDR_TYPE_IPV6;</span><br><span style="color: hsl(120, 100%, 40%);">+ case AF_INET:</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(&uaddr->v4, &osa->u.sin.sin_addr, sizeof(osa->u.sin.sin_addr));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (port)</span><br><span style="color: hsl(120, 100%, 40%);">+ *port = ntohs(osa->u.sin.sin_port);</span><br><span style="color: hsl(120, 100%, 40%);">+ return HNB_PRIM_ADDR_TYPE_IPV4;</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ return HNB_PRIM_ADDR_TYPE_UNSPEC;</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> static int llsk_opened_cb(struct osmo_prim_srv *srv)</span><br><span> {</span><br><span> struct hnb *hnb = (struct hnb *)osmo_prim_srv_get_priv(srv);</span><br><span>@@ -73,7 +128,8 @@</span><br><span> if (!hnb->llsk)</span><br><span> return false;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (hnb->llsk_valid_sapi_mask & (1 << HNB_PRIM_SAPI_IUH))</span><br><span style="color: hsl(120, 100%, 40%);">+ if (hnb->llsk_valid_sapi_mask & (1 << HNB_PRIM_SAPI_IUH) &&</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->llsk_valid_sapi_mask & (1 << HNB_PRIM_SAPI_AUDIO))</span><br><span> return true;</span><br><span> return false;</span><br><span> }</span><br><span>@@ -108,10 +164,11 @@</span><br><span> case HNB_PRIM_SAPI_IUH:</span><br><span> return llsk_rx_iuh(hnb, oph);</span><br><span> case HNB_PRIM_SAPI_GTP:</span><br><span style="color: hsl(0, 100%, 40%);">- case HNB_PRIM_SAPI_AUDIO:</span><br><span> LOGP(DLLSK, LOGL_ERROR, "Rx SAPI %u not yet implemented (len=%u)\n",</span><br><span> oph->sap, msgb_length(oph->msg));</span><br><span> return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ case HNB_PRIM_SAPI_AUDIO:</span><br><span style="color: hsl(120, 100%, 40%);">+ return llsk_rx_audio(hnb, oph);</span><br><span> default:</span><br><span> LOGP(DLLSK, LOGL_ERROR, "Rx for unknwon SAPI %u (len=%u)\n",</span><br><span> oph->sap, msgb_length(oph->msg));</span><br><span>diff --git a/src/osmo-hnodeb/llsk_audio.c b/src/osmo-hnodeb/llsk_audio.c</span><br><span>new file mode 100644</span><br><span>index 0000000..4fa8079</span><br><span>--- /dev/null</span><br><span>+++ b/src/osmo-hnodeb/llsk_audio.c</span><br><span>@@ -0,0 +1,296 @@</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <unistd.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 <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/socket.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <inttypes.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/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/socket.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/trau/osmo_ortp.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%);">+#include <osmocom/hnodeb/llsk.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnodeb/hnb_prim.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnodeb/rtp.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t llsk_audio_prim_size_tbl[4][_HNB_AUDIO_PRIM_MAX] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ [PRIM_OP_REQUEST] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ [HNB_AUDIO_PRIM_CONN_ESTABLISH] = sizeof(struct hnb_audio_conn_establish_req_param),</span><br><span style="color: hsl(120, 100%, 40%);">+ [HNB_AUDIO_PRIM_CONN_RELEASE] = sizeof(struct hnb_audio_conn_release_req_param),</span><br><span style="color: hsl(120, 100%, 40%);">+ [HNB_AUDIO_PRIM_CONN_DATA] = sizeof(struct hnb_audio_conn_data_req_param),</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ [PRIM_OP_RESPONSE] = {},</span><br><span style="color: hsl(120, 100%, 40%);">+ [PRIM_OP_INDICATION] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ [HNB_AUDIO_PRIM_CONN_DATA] = sizeof(struct hnb_audio_conn_data_ind_param),</span><br><span style="color: hsl(120, 100%, 40%);">+ },</span><br><span style="color: hsl(120, 100%, 40%);">+ [PRIM_OP_CONFIRM] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ [HNB_AUDIO_PRIM_CONN_ESTABLISH] = sizeof(struct hnb_audio_conn_establish_cnf_param),</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 inline size_t llsk_audio_prim_size(enum hnb_audio_prim_type ptype, enum osmo_prim_operation op)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t val = llsk_audio_prim_size_tbl[op][ptype];</span><br><span style="color: hsl(120, 100%, 40%);">+ if (val == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_FATAL, "Expected prim_size != 0 for ptype=%u op=%u\n", ptype, op);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_panic("Expected prim_size != 0 for ptype=%u op=%u\n", ptype, op);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return val;</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 value_string hnb_audio_prim_type_names[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_VALUE_STRING(HNB_AUDIO_PRIM_CONN_ESTABLISH),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_VALUE_STRING(HNB_AUDIO_PRIM_CONN_RELEASE),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_VALUE_STRING(HNB_AUDIO_PRIM_CONN_DATA),</span><br><span style="color: hsl(120, 100%, 40%);">+ { 0, 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 struct hnb_audio_prim *hnb_audio_prim_alloc(enum hnb_audio_prim_type ptype, enum osmo_prim_operation op, size_t extra_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_prim_hdr *oph;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t len = llsk_audio_prim_size(ptype, op);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ oph = osmo_prim_msgb_alloc(HNB_PRIM_SAPI_AUDIO, ptype, op, sizeof(*oph) + len + extra_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!oph)</span><br><span style="color: hsl(120, 100%, 40%);">+ return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_put(oph->msg, len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return (struct hnb_audio_prim *)oph;</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 hnb_audio_prim *hnb_audio_makeprim_conn_establish_cnf(uint32_t context_id, uint8_t error_code,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t local_rtp_port, uint8_t local_rtp_address_type,</span><br><span style="color: hsl(120, 100%, 40%);">+ const union u_addr *local_rtp_addr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_audio_prim *audio_prim;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ audio_prim = hnb_audio_prim_alloc(HNB_AUDIO_PRIM_CONN_ESTABLISH, PRIM_OP_CONFIRM, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ audio_prim->u.conn_establish_cnf.context_id = context_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ audio_prim->u.conn_establish_cnf.local_rtp_port = local_rtp_port;</span><br><span style="color: hsl(120, 100%, 40%);">+ audio_prim->u.conn_establish_cnf.error_code = error_code;</span><br><span style="color: hsl(120, 100%, 40%);">+ audio_prim->u.conn_establish_cnf.local_rtp_address_type = local_rtp_address_type;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (local_rtp_addr)</span><br><span style="color: hsl(120, 100%, 40%);">+ audio_prim->u.conn_establish_cnf.local_rtp_addr = *local_rtp_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return audio_prim;</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 hnb_audio_prim *hnb_audio_makeprim_conn_data_ind(uint32_t context_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t domain,</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint8_t *data,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t data_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_audio_prim *audio_prim;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ audio_prim = hnb_audio_prim_alloc(HNB_AUDIO_PRIM_CONN_DATA, PRIM_OP_INDICATION, data_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ audio_prim->u.conn_data_ind.context_id = context_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ audio_prim->u.conn_data_ind.data_len = data_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (data_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_put(audio_prim->hdr.msg, data_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(audio_prim->u.conn_data_ind.data, data, data_len);</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 audio_prim;</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 llsk_audio_tx_conn_data_ind(struct hnb_ue *ue, const uint8_t *payload, uint32_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_audio_prim *audio_prim;</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%);">+ LOGUE(ue, DLLSK, LOGL_INFO, "Tx AUDIO-CONN_DATA.ind\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ audio_prim = hnb_audio_makeprim_conn_data_ind(ue->conn_id, 0 /* CS */, payload, len);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = osmo_prim_srv_send(ue->hnb->llsk, audio_prim->hdr.msg)) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DLLSK, LOGL_ERROR, "Failed sending AUDIO-CONN_DATA.ind\n");</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 _send_conn_establish_cnf_failed(struct hnb *hnb, uint32_t context_id, uint8_t error_code)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_audio_prim *audio_prim;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_ERROR, "Tx AUDIO-CONN_ESTABLISH.cnf: ctx=%u error_code=%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ context_id, error_code);</span><br><span style="color: hsl(120, 100%, 40%);">+ audio_prim = hnb_audio_makeprim_conn_establish_cnf(context_id, error_code, 0, HNB_PRIM_ADDR_TYPE_UNSPEC, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = osmo_prim_srv_send(hnb->llsk, audio_prim->hdr.msg)) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_ERROR, "Failed sending AUDIO-CONN_ESTABLISH.cnf context_id=%u error_code=%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ context_id, error_code);</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%);">+static int llsk_rx_audio_conn_establish_req(struct hnb *hnb, struct hnb_audio_conn_establish_req_param *ce_req)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_ue *ue;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_audio_prim *audio_prim;</span><br><span style="color: hsl(120, 100%, 40%);">+ int af;</span><br><span style="color: hsl(120, 100%, 40%);">+ char rem_addrstr[INET6_ADDRSTRLEN+32];</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_sockaddr rem_osa = {0};</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_sockaddr loc_osa = {0};</span><br><span style="color: hsl(120, 100%, 40%);">+ union u_addr loc_uaddr = {0};</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t loc_port;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = ll_addr2osa(ce_req->remote_rtp_address_type, &ce_req->remote_rtp_addr, ce_req->remote_rtp_port, &rem_osa);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: ctx=%u with unexpected address type %u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ ce_req->context_id, ce_req->remote_rtp_address_type);</span><br><span style="color: hsl(120, 100%, 40%);">+ return _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_sockaddr_to_str_buf(rem_addrstr, sizeof(rem_addrstr), &rem_osa);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_INFO, "Rx AUDIO-CONN_ESTABLISH.req ctx=%u rem_addr=%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ ce_req->context_id, rem_addrstr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((af = ll_addr_type2af(ce_req->remote_rtp_address_type)) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: ctx=%u with unexpected address type %u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ ce_req->context_id, ce_req->remote_rtp_address_type);</span><br><span style="color: hsl(120, 100%, 40%);">+ return _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 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%);">+ ue = hnb_find_ue_by_id(hnb, ce_req->context_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ue) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: UE not found! ctx=%u rem_addr=%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ ce_req->context_id, rem_addrstr);</span><br><span style="color: hsl(120, 100%, 40%);">+ return _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ue->conn_cs.active) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: CS chan not active! rem_addr=%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rem_addrstr);</span><br><span style="color: hsl(120, 100%, 40%);">+ return _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 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%);">+ /* Create the socket: */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = hnb_ue_voicecall_setup(ue, &rem_osa, &loc_osa)) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: Failed to set up audio socket rem_addr=%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rem_addrstr);</span><br><span style="color: hsl(120, 100%, 40%);">+ return _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 4);</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%);">+ /* Convert resulting local address back to LLSK format: */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (osa2_ll_addr(&loc_osa, &loc_uaddr, &loc_port) != ce_req->remote_rtp_address_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: Failed to provide proper local address rem_addr=%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rem_addrstr);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto release_sock;</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%);">+ /* Submit successful confirmation */</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DLLSK, LOGL_INFO, "Tx AUDIO-CONN_ESTABLISH.cnf: error_code=0 rem_addr=%s loc_addr=%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rem_addrstr, osmo_sockaddr_to_str(&loc_osa));</span><br><span style="color: hsl(120, 100%, 40%);">+ audio_prim = hnb_audio_makeprim_conn_establish_cnf(ce_req->context_id, 0, loc_port,</span><br><span style="color: hsl(120, 100%, 40%);">+ ce_req->remote_rtp_address_type, &loc_uaddr);</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((rc = osmo_prim_srv_send(hnb->llsk, audio_prim->hdr.msg)) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DLLSK, LOGL_ERROR, "Failed sending AUDIO-CONN_ESTABLISH.cnf error_code=0\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ goto release_sock;</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%);">+release_sock:</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb_ue_voicecall_release(ue);</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 llsk_rx_audio_conn_release_req(struct hnb *hnb, struct hnb_audio_conn_release_req_param *rel_req)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_ue *ue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_DEBUG, "Rx AUDIO-CONN_RELEASE.req ctx=%u\n", rel_req->context_id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ue = hnb_find_ue_by_id(hnb, rel_req->context_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ue) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_RELEASE.req: UE not found! ctx=%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rel_req->context_id);</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%);">+ /* Release RTP socket: */</span><br><span style="color: hsl(120, 100%, 40%);">+ return hnb_ue_voicecall_release(ue);</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 llsk_rx_audio_conn_data_req(struct hnb *hnb, struct hnb_audio_conn_data_req_param *data_req)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_ue *ue;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_DEBUG, "Rx AUDIO-CONN_DATA.req ctx=%u data_len=%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ data_req->context_id, data_req->data_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ue = hnb_find_ue_by_id(hnb, data_req->context_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ue) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_DATA.req: UE not found! ctx=%u data_len=%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ data_req->context_id, data_req->data_len);</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%);">+ /* TODO: transmit data_req->data through RTP/Iu-UP socket */</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_rtp_send_frame_ext(ue->conn_cs.rtp.socket, data_req->data,</span><br><span style="color: hsl(120, 100%, 40%);">+ data_req->data_len, GSM_RTP_DURATION, false);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_DATA.req: UE not found! ctx=%u data_len=%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ data_req->context_id, data_req->data_len);</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%);">+int llsk_rx_audio(struct hnb *hnb, struct osmo_prim_hdr *oph)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t prim_size = llsk_audio_prim_size(oph->primitive, oph->operation);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (msgb_length(oph->msg) < prim_size) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_ERROR, "Rx AUDIO-%s.%s with length %u < %zu\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ get_value_string(hnb_audio_prim_type_names, oph->primitive),</span><br><span style="color: hsl(120, 100%, 40%);">+ get_value_string(osmo_prim_op_names, oph->operation),</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_length(oph->msg), prim_size);</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 (oph->operation) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case PRIM_OP_REQUEST:</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (oph->primitive) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case HNB_AUDIO_PRIM_CONN_ESTABLISH:</span><br><span style="color: hsl(120, 100%, 40%);">+ return llsk_rx_audio_conn_establish_req(hnb, (struct hnb_audio_conn_establish_req_param *)msgb_data(oph->msg));</span><br><span style="color: hsl(120, 100%, 40%);">+ case HNB_AUDIO_PRIM_CONN_RELEASE:</span><br><span style="color: hsl(120, 100%, 40%);">+ return llsk_rx_audio_conn_release_req(hnb, (struct hnb_audio_conn_release_req_param *)msgb_data(oph->msg));</span><br><span style="color: hsl(120, 100%, 40%);">+ case HNB_AUDIO_PRIM_CONN_DATA:</span><br><span style="color: hsl(120, 100%, 40%);">+ return llsk_rx_audio_conn_data_req(hnb, (struct hnb_audio_conn_data_req_param *)msgb_data(oph->msg));</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_ERROR, "Rx llsk-audio unknown primitive %u (len=%u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ oph->primitive, msgb_length(oph->msg));</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%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case PRIM_OP_RESPONSE:</span><br><span style="color: hsl(120, 100%, 40%);">+ case PRIM_OP_INDICATION:</span><br><span style="color: hsl(120, 100%, 40%);">+ case PRIM_OP_CONFIRM:</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DLLSK, LOGL_ERROR, "Rx llsk-audio unexpected primitive operation %s::%s (len=%u)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ get_value_string(hnb_audio_prim_type_names, oph->primitive),</span><br><span style="color: hsl(120, 100%, 40%);">+ get_value_string(osmo_prim_op_names, oph->operation),</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_length(oph->msg));</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>diff --git a/src/osmo-hnodeb/main.c b/src/osmo-hnodeb/main.c</span><br><span>index 6728a07..9af83ea 100644</span><br><span>--- a/src/osmo-hnodeb/main.c</span><br><span>+++ b/src/osmo-hnodeb/main.c</span><br><span>@@ -41,6 +41,8 @@</span><br><span> #include <osmocom/vty/cpu_sched_vty.h></span><br><span> #include <osmocom/vty/ports.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/trau/osmo_ortp.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include <osmocom/ranap/ranap_common.h> /* ranap_set_log_area() */</span><br><span> </span><br><span> #include <osmocom/hnodeb/hnbap.h></span><br><span>@@ -224,6 +226,7 @@</span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span> int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ void *tall_rtp_ctx;</span><br><span> </span><br><span> /* Track the use of talloc NULL memory contexts */</span><br><span> talloc_enable_null_tracking();</span><br><span>@@ -246,6 +249,11 @@</span><br><span> osmo_talloc_vty_add_cmds();</span><br><span> osmo_cpu_sched_vty_init(tall_hnb_ctx);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* allocate a talloc pool for ORTP to ensure it doesn't have to go back</span><br><span style="color: hsl(120, 100%, 40%);">+ * to the libc malloc all the time */</span><br><span style="color: hsl(120, 100%, 40%);">+ tall_rtp_ctx = talloc_pool(tall_hnb_ctx, 262144);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_rtp_init(tall_rtp_ctx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> g_hnb = hnb_alloc(tall_hnb_ctx);</span><br><span> hnb_vty_init();</span><br><span> </span><br><span>diff --git a/src/osmo-hnodeb/rtp.c b/src/osmo-hnodeb/rtp.c</span><br><span>new file mode 100644</span><br><span>index 0000000..cc03c6c</span><br><span>--- /dev/null</span><br><span>+++ b/src/osmo-hnodeb/rtp.c</span><br><span>@@ -0,0 +1,212 @@</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "config.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/socket.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/trau/osmo_ortp.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/hnodeb/rtp.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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Mixture between osmo_rtp_get_bound_addr and osmo_rtp_get_bound_ip_port using osmo_sockaddr */</span><br><span style="color: hsl(120, 100%, 40%);">+/*static int rtp_get_bound_addr(struct osmo_rtp_socket *rs, struct osmo_sockaddr *osa)</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%);">+ socklen_t alen = sizeof(*osa);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = getsockname(rs->rtp_bfd.fd, (struct sockaddr *)&osa->u.sa, &alen);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DRTP, LOGL_ERROR, "getsockname(%d) failed: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rs->rtp_bfd.fd, strerror(errno));</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%);">+ LOGP(DRTP, LOGL_DEBUG, "rtp socket: %s\n", osmo_sock_get_name2(rs->rtp_bfd.fd));</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%);">+/* osmo_rtp_socket_connect() is broken, OS#5356 */</span><br><span style="color: hsl(120, 100%, 40%);">+static int rtp_get_bound_addr(struct osmo_rtp_socket *rs, const struct osmo_sockaddr *rem_addr, struct osmo_sockaddr *osa)</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%);">+ uint16_t port;</span><br><span style="color: hsl(120, 100%, 40%);">+ socklen_t alen = sizeof(*osa);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* First, retrieve bound port using getsockname: */</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = getsockname(rs->rtp_bfd.fd, (struct sockaddr *)&osa->u.sa, &alen);</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%);">+ switch (osa->u.sa.sa_family) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case AF_INET6:</span><br><span style="color: hsl(120, 100%, 40%);">+ port = ntohs(osa->u.sin6.sin6_port);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case AF_INET:</span><br><span style="color: hsl(120, 100%, 40%);">+ port = ntohs(osa->u.sin.sin_port);</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%);">+ 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%);">+ /* osmo_rtp_socket_connect() is broken, OS#5356, so we didn't connect()</span><br><span style="color: hsl(120, 100%, 40%);">+ * and hence local_addr may still be unresolved (0.0.0.0) in the socket.</span><br><span style="color: hsl(120, 100%, 40%);">+ * let's get it from OS regular routing: */</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_sockaddr_local_ip(osa, rem_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DRTP, LOGL_ERROR, "osmo_sockaddr_local_ip(%d) failed: err=%d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rs->rtp_bfd.fd, -rc);</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%);">+ /* Copy back the correct port to the returned address: */</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (osa->u.sa.sa_family) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case AF_INET6:</span><br><span style="color: hsl(120, 100%, 40%);">+ osa->u.sin6.sin6_port = htons(port);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case AF_INET:</span><br><span style="color: hsl(120, 100%, 40%);">+ osa->u.sin.sin_port = htons(port);</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%);">+ return -EINVAL;</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 rtp_bind(struct hnb *hnb, struct osmo_rtp_socket *rs, const char *ip)</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%);">+ unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int tries;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ tries = (hnb->rtp.port_range_end - hnb->rtp.port_range_start) / 2;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < tries; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (hnb->rtp.port_range_next >= hnb->rtp.port_range_end)</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->rtp.port_range_next = hnb->rtp.port_range_start;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_rtp_socket_bind(rs, ip, hnb->rtp.port_range_next);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->rtp.port_range_next += 2;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc != 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (hnb->rtp.ip_dscp != -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (osmo_rtp_socket_set_dscp(rs, hnb->rtp.ip_dscp))</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DRTP, LOGL_ERROR, "failed to set DSCP=%d: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->rtp.ip_dscp, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (hnb->rtp.priority != -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (osmo_rtp_socket_set_priority(rs, hnb->rtp.priority))</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DRTP, LOGL_ERROR, "failed to set socket priority %d: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->rtp.priority, strerror(errno));</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%);">+ 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%);">+static void rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl,</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int rtp_pl_len, uint16_t seq_number,</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t timestamp, bool marker)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb_ue *ue = (struct hnb_ue *)rs->priv;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DRTP, LOGL_DEBUG, "Rx RTP seq=%u ts=%u M=%u pl=%p len=%u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_number, timestamp, marker, rtp_pl, rtp_pl_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ llsk_audio_tx_conn_data_ind(ue, rtp_pl, rtp_pl_len);</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_ue_voicecall_setup(struct hnb_ue *ue, const struct osmo_sockaddr *rem_addr, struct osmo_sockaddr *loc_addr)</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%);">+ char cname[256+4];</span><br><span style="color: hsl(120, 100%, 40%);">+ char name[32];</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_rtp_socket *rs;</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *local_wildcard_ipstr = "0.0.0.0";</span><br><span style="color: hsl(120, 100%, 40%);">+ char remote_ipstr[INET6_ADDRSTRLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t remote_port;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct hnb *hnb = ue->hnb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (osmo_sockaddr_to_str_and_uint(remote_ipstr, sizeof(remote_ipstr), &remote_port, &rem_addr->u.sa) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DRTP, LOGL_ERROR, "Failed parsing remote address!\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 (ue->conn_cs.rtp.socket) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DRTP, LOGL_ERROR, "Setting up rtp socket but it already exists!\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%);">+ rs = ue->conn_cs.rtp.socket = osmo_rtp_socket_create(ue, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_rtp_socket_set_param(rs,</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->rtp.jitter_adaptive ?</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_RTP_P_JIT_ADAP :</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_RTP_P_JITBUF,</span><br><span style="color: hsl(120, 100%, 40%);">+ hnb->rtp.jitter_buf_ms);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DRTP, LOGL_ERROR, "Failed to set RTP socket parameters: %s\n", strerror(-rc));</span><br><span style="color: hsl(120, 100%, 40%);">+ goto free_ret;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ rs->priv = ue;</span><br><span style="color: hsl(120, 100%, 40%);">+ rs->rx_cb = &rtp_rx_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = rtp_bind(hnb, rs, local_wildcard_ipstr);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DRTP, LOGL_ERROR, "Failed to bind RTP/RTCP sockets\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ goto free_ret;</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%);">+ /* Ensure RTCP SDES contains some useful information */</span><br><span style="color: hsl(120, 100%, 40%);">+ snprintf(cname, sizeof(cname), "hnb@%s", local_wildcard_ipstr);</span><br><span style="color: hsl(120, 100%, 40%);">+ snprintf(name, sizeof(name), "ue@%u", ue->conn_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_rtp_set_source_desc(rs, cname, name, NULL, NULL, NULL,</span><br><span style="color: hsl(120, 100%, 40%);">+ "OsmoHNodeB-" PACKAGE_VERSION, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = osmo_rtp_socket_connect(rs, remote_ipstr, remote_port);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DRTP, LOGL_ERROR, "Failed to connect RTP/RTCP sockets\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ goto free_ret;</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_rtp_socket_connect() is broken, OS#5356 */</span><br><span style="color: hsl(120, 100%, 40%);">+ //rc = rtp_get_bound_addr(rs, loc_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = rtp_get_bound_addr(rs, rem_addr, loc_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGUE(ue, DRTP, LOGL_ERROR, "Cannot obtain locally bound IP/port: %d\n", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+ goto free_ret;</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%);">+free_ret:</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_rtp_socket_free(ue->conn_cs.rtp.socket);</span><br><span style="color: hsl(120, 100%, 40%);">+ ue->conn_cs.rtp.socket = NULL;</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%);">+int hnb_ue_voicecall_release(struct hnb_ue *ue)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ue->conn_cs.rtp.socket)</span><br><span style="color: hsl(120, 100%, 40%);">+ return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_rtp_socket_free(ue->conn_cs.rtp.socket);</span><br><span style="color: hsl(120, 100%, 40%);">+ ue->conn_cs.rtp.socket = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</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/+/26502">change 26502</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/+/26502"/><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: I9909a7c054ddaabb1bb63d7d06331cc79f642b5d </div>
<div style="display:none"> Gerrit-Change-Number: 26502 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </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: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>