Change in osmo-hnodeb[master]: Update AUDIO and GTP SAPs to support multiple conns per UE

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

pespin gerrit-no-reply at lists.osmocom.org
Tue Dec 14 17:59:41 UTC 2021


pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-hnodeb/+/26570 )


Change subject: Update AUDIO and GTP SAPs to support multiple conns per UE
......................................................................

Update AUDIO and GTP SAPs to support multiple conns per UE

This is needed for instance:
* AUDIO: video calls
* GTP: secondary pdp contexts

For better abstraction, now both AUDIO and GTP conns use unique ID
namespaces, and one ID is used to identify each one. Each conn relate in
turn to a UE since a context_id is passed during connection
establishment.

Related: SYS#5516
Change-Id: Ib3f60d5ba21defe5259c25e2034fc2217c4d93df
---
M doc/hnodeb.msc
M include/osmocom/hnodeb/gtp.h
M include/osmocom/hnodeb/hnb_prim.h
M include/osmocom/hnodeb/hnodeb.h
M include/osmocom/hnodeb/llsk.h
M include/osmocom/hnodeb/rtp.h
M src/osmo-hnodeb/gtp.c
M src/osmo-hnodeb/hnb.c
M src/osmo-hnodeb/llsk_audio.c
M src/osmo-hnodeb/llsk_gtp.c
M src/osmo-hnodeb/rtp.c
11 files changed, 273 insertions(+), 182 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-hnodeb refs/changes/70/26570/1

diff --git a/doc/hnodeb.msc b/doc/hnodeb.msc
index 6ad6e7c..10de180 100644
--- a/doc/hnodeb.msc
+++ b/doc/hnodeb.msc
@@ -43,19 +43,19 @@
 	---  [ label = "Subscriber set up PS data:" ];
 	hnodeb <= hnbgw [label="RANAP RAB-Assignment Request(TEI, ADDR)"];
 	trx <= hnodeb [label="IUH-CONN_DATA.ind[RANAP RAB-Assignment Request(remote_ip, remote_port, remote_tei)]"];
-	trx => hnodeb [label="GTP-CONN_ESTABLISH.req(remote_ip,remote_port,remote_tei)"];
+	trx => hnodeb [label="GTP-CONN_ESTABLISH.req(context_id,remote_ip,remote_port,remote_tei)"];
 	...  [ label = "HnodeB sets up GTP-U connection" ];
-	trx <= hnodeb [label="GTP-CONN_ESTABLISH.cnf(local_ip,local_port,local_tei,remote_tei)"];
+	trx <= hnodeb [label="GTP-CONN_ESTABLISH.cnf(context_id,gtp_conn_id,local_ip,local_port,local_tei)"];
 	|||;
 	...;
 	|||;
 	|||;
 	---  [ label = "PS data transmission over GTP-U:" ];
 	ue => trx [label="..."];
-	trx => hnodeb [label="GTP-CONN_DATA.req[remote_tei,payload]"];
+	trx => hnodeb [label="GTP-CONN_DATA.req[gtp_conn_id,payload]"];
 	hnodeb => ggsn [label="GTP-U(remote_tei, local_addr, remote_addr, payload)"];
 	hnodeb <= ggsn [label="GTP-U(local_tei, remote_addr, local_addr, payload)"];
-	trx <= hnodeb [label="GTP-CONN_DATA.ind[local_tei,payload]"];
+	trx <= hnodeb [label="GTP-CONN_DATA.ind[gtp_conn_id,payload]"];
 	ue <= trx [label="..."];
 	|||;
 	...;
@@ -67,7 +67,7 @@
 	hnodeb <= hnbgw [label="RANAP IU Release Command"];
 	trx <= hnodeb [label="IUH-CONN_DATA.ind[RANAP IU Release Command]"];
 	...;
-	trx => hnodeb [label="GTP-CONN_RELEASE.req(remote_tei)"];
+	trx => hnodeb [label="GTP-CONN_RELEASE.req(gtp_conn_id)"];
 
 	trx => hnodeb [label="IUH-CONN_RELEASE.req[RANAP IU Release Complete]"];
 	hnodeb => hnbgw [label="RUA-Disconnect(RANAP IU Release Complete)"];
diff --git a/include/osmocom/hnodeb/gtp.h b/include/osmocom/hnodeb/gtp.h
index af9e007..477e82b 100644
--- a/include/osmocom/hnodeb/gtp.h
+++ b/include/osmocom/hnodeb/gtp.h
@@ -18,7 +18,11 @@
  */
 #pragma once
 
+#include <gtp.h>
+#include <pdp.h>
+
 #include <osmocom/core/socket.h>
+#include <osmocom/core/linuxlist.h>
 
 struct hnb;
 struct hnb_ue;
@@ -26,7 +30,19 @@
 int hnb_gtp_bind(struct hnb *hnb);
 void hnb_gtp_unbind(struct hnb *hnb);
 
-int hnb_ue_gtp_bind(struct hnb_ue *ue, const struct osmo_sockaddr *rem_addr, uint32_t rem_tei,
-		     struct osmo_sockaddr *loc_addr, uint32_t *loc_tei);
-int hnb_ue_gtp_unbind(struct hnb_ue *ue);
-int hnb_ue_gtp_tx(struct hnb_ue *ue, void *gtpu_payload, unsigned gtpu_payload_len);
+struct gtp_conn {
+	struct llist_head list; /* Item in struct hnb->ue_list */
+	struct hnb_ue *ue; /* backpointer */
+	uint32_t id;
+	struct osmo_sockaddr loc_addr;
+	struct osmo_sockaddr rem_addr;
+	uint32_t loc_tei;
+	uint32_t rem_tei;
+	struct pdp_t *pdp_lib;
+};
+
+struct gtp_conn *gtp_conn_alloc(struct hnb_ue *ue);
+void gtp_conn_free(struct gtp_conn *conn);
+
+int gtp_conn_setup(struct gtp_conn *conn, const struct osmo_sockaddr *rem_addr, uint32_t rem_tei);
+int gtp_conn_tx(struct gtp_conn *conn, void *gtpu_payload, unsigned gtpu_payload_len);
diff --git a/include/osmocom/hnodeb/hnb_prim.h b/include/osmocom/hnodeb/hnb_prim.h
index f0e3a96..0b0a545 100644
--- a/include/osmocom/hnodeb/hnb_prim.h
+++ b/include/osmocom/hnodeb/hnb_prim.h
@@ -197,6 +197,7 @@
 /* HNB_AUDIO_PRIM_CONN_ESTABLISH, DL */
 struct hnb_audio_conn_establish_cnf_param {
 	uint32_t context_id;
+	uint32_t audio_conn_id;
 	uint16_t local_rtp_port;
 	uint8_t error_code; /* 0 = success, !0 = failure */
 	uint8_t local_rtp_address_type; /* enum u_addr_type */
@@ -205,19 +206,19 @@
 
 /* HNB_AUDIO_PRIM_CONN_RELEASE, UL */
 struct hnb_audio_conn_release_req_param {
-	uint32_t context_id;
+	uint32_t audio_conn_id;
 } __attribute__ ((packed));
 
 /* HNB_AUDIO_PRIM_CONN_DATA, UL */
 struct hnb_audio_conn_data_req_param {
-	uint32_t context_id;
+	uint32_t audio_conn_id;
 	uint32_t data_len; /* RTP payload length in bytes */
 	uint8_t data[0]; /* RTP payload (aka IP packet) */
 } __attribute__ ((packed));
 
 /* HNB_AUDIO_PRIM_CONN_DATA, DL */
 struct hnb_audio_conn_data_ind_param {
-	uint32_t context_id;
+	uint32_t audio_conn_id;
 	uint32_t data_len; /* RTP payload length in bytes */
 	uint8_t data[0]; /* RTP payload (aka IP packet) */
 } __attribute__ ((packed));
@@ -256,6 +257,7 @@
 /* HNB_GTP_PRIM_CONN_ESTABLISH, DL */
 struct hnb_gtp_conn_establish_cnf_param {
 	uint32_t context_id;
+	uint32_t gtp_conn_id;
 	uint32_t local_tei;
 	uint8_t error_code; /* 0 = success, !0 = failure */
 	uint8_t local_gtpu_address_type;   /* enum u_addr_type */
@@ -264,28 +266,19 @@
 
 /* HNB_GTP_PRIM_CONN_RELEASE, UL */
 struct hnb_gtp_conn_release_req_param {
-	uint32_t context_id;
-	uint32_t remote_tei;
-} __attribute__ ((packed));
-
-/* HNB_GTP_PRIM_CONN_RELEASE, DL */
-struct hnb_gtp_conn_release_ind_param {
-	uint32_t context_id;
-	uint32_t local_tei;
+	uint32_t gtp_conn_id;
 } __attribute__ ((packed));
 
 /* HNB_GTP_PRIM_CONN_DATA, DL */
 struct hnb_gtp_conn_data_ind_param {
-	uint32_t context_id;
-	uint32_t local_tei;
+	uint32_t gtp_conn_id;
 	uint32_t data_len; /* GTP-U payload length in bytes */
 	uint8_t data[0]; /* GTP-U payload (aka IP packet) */
 } __attribute__ ((packed));
 
 /* HNB_GTP_PRIM_CONN_DATA, UL */
 struct hnb_gtp_conn_data_req_param {
-	uint32_t context_id;
-	uint32_t remote_tei;
+	uint32_t gtp_conn_id;
 	uint32_t data_len; /* GTP-U payload length in bytes */
 	uint8_t data[0]; /* GTP-U payload (aka IP packet) */
 } __attribute__ ((packed));
diff --git a/include/osmocom/hnodeb/hnodeb.h b/include/osmocom/hnodeb/hnodeb.h
index 52d1bec..82b43c3 100644
--- a/include/osmocom/hnodeb/hnodeb.h
+++ b/include/osmocom/hnodeb/hnodeb.h
@@ -35,9 +35,6 @@
 #include <osmocom/gsm/protocol/gsm_23_003.h>
 #include <osmocom/netif/stream.h>
 
-#include <gtp.h>
-#include <pdp.h>
-
 #include <osmocom/hnodeb/llsk.h>
 
 enum {
@@ -62,16 +59,12 @@
 	struct hnb_ue_cs_ctx {
 		bool active; /* Is this chan in use? */
 		bool conn_est_cnf_pending; /* Did we send CONN_ESTABLISH_CNF to lower layers? */
-		struct {
-			struct osmo_rtp_socket *socket;
-		} rtp;
+		struct llist_head conn_list; /* list of struct rtp_conn */
 	} conn_cs;
 	struct hnb_ue_ps_ctx {
 		bool active; /* Is this chan in use? */
 		bool conn_est_cnf_pending; /* Did we send CONN_ESTABLISH_CNF to lower layers? */
-		uint32_t local_tei;
-		uint32_t remote_tei;
-		struct pdp_t *pdp_lib;
+		struct llist_head conn_list; /* list of struct gtp_conn */
 	} conn_ps;
 };
 struct hnb_ue *hnb_ue_alloc(struct hnb *hnb, uint32_t conn_id);
@@ -132,9 +125,11 @@
 struct hnb *hnb_alloc(void *tall_ctx);
 void hnb_free(struct hnb *hnb);
 struct hnb_ue *hnb_find_ue_by_id(const struct hnb *hnb, uint32_t conn_id);
-struct hnb_ue *hnb_find_ue_by_tei(const struct hnb *hnb, uint32_t tei, bool is_remote);
 struct hnb_ue *hnb_find_ue_by_imsi(const struct hnb *hnb, char *imsi);
 
+struct rtp_conn *hnb_find_rtp_conn_by_id(const struct hnb *hnb, uint32_t audio_conn_id);
+struct gtp_conn *hnb_find_gtp_conn_by_id(const struct hnb *hnb, uint32_t gtp_conn_id);
+
 extern void *tall_hnb_ctx;
 extern struct hnb *g_hnb;
 
diff --git a/include/osmocom/hnodeb/llsk.h b/include/osmocom/hnodeb/llsk.h
index 6d98cd0..fe1dce1 100644
--- a/include/osmocom/hnodeb/llsk.h
+++ b/include/osmocom/hnodeb/llsk.h
@@ -27,7 +27,7 @@
 #include <osmocom/hnodeb/hnb_prim.h>
 
 struct hnb;
-struct hnb_ue;
+struct rtp_conn;
 
 int hnb_llsk_alloc(struct hnb *hnb);
 bool hnb_llsk_connected(const struct hnb *hnb);
@@ -53,9 +53,8 @@
 
 extern const struct value_string hnb_audio_prim_type_names[];
 int llsk_rx_audio(struct hnb *hnb, struct osmo_prim_hdr *oph);
-int llsk_audio_tx_conn_data_ind(struct hnb_ue *ue, const uint8_t *payload, uint32_t len);
+int llsk_audio_tx_conn_data_ind(struct rtp_conn *conn, const uint8_t *payload, uint32_t len);
 
 extern const struct value_string hnb_gtp_prim_type_names[];
 int llsk_rx_gtp(struct hnb *hnb, struct osmo_prim_hdr *oph);
-struct hnb_gtp_prim *hnb_gtp_makeprim_conn_data_ind(uint32_t context_id, uint32_t local_tei,
-						    const uint8_t *data, uint32_t data_len);
+struct hnb_gtp_prim *hnb_gtp_makeprim_conn_data_ind(uint32_t gtp_conn_id, const uint8_t *data, uint32_t data_len);
diff --git a/include/osmocom/hnodeb/rtp.h b/include/osmocom/hnodeb/rtp.h
index 01ec1c4..8035175 100644
--- a/include/osmocom/hnodeb/rtp.h
+++ b/include/osmocom/hnodeb/rtp.h
@@ -19,9 +19,21 @@
 #pragma once
 
 #include <osmocom/core/socket.h>
+#include <osmocom/core/linuxlist.h>
 
 struct hnb;
 struct hnb_ue;
 
-int hnb_ue_voicecall_setup(struct hnb_ue *ue, const struct osmo_sockaddr *rem_addr, struct osmo_sockaddr *loc_addr);
-int hnb_ue_voicecall_release(struct hnb_ue *ue);
+struct rtp_conn {
+	struct llist_head list; /* Item in struct hnb->ue_list */
+	struct hnb_ue *ue; /* backpointer */
+	uint32_t id;
+	struct osmo_rtp_socket *socket;
+	struct osmo_sockaddr loc_addr;
+	struct osmo_sockaddr rem_addr;
+};
+
+struct rtp_conn *rtp_conn_alloc(struct hnb_ue *ue);
+void rtp_conn_free(struct rtp_conn *conn);
+
+int rtp_conn_setup(struct rtp_conn *conn, const struct osmo_sockaddr *rem_addr);
diff --git a/src/osmo-hnodeb/gtp.c b/src/osmo-hnodeb/gtp.c
index 4695ea9..c26efa5 100644
--- a/src/osmo-hnodeb/gtp.c
+++ b/src/osmo-hnodeb/gtp.c
@@ -27,8 +27,38 @@
 #include <gtp.h>
 #include <pdp.h>
 
+static uint32_t next_gtp_conn_id = 0;
+
+struct gtp_conn *gtp_conn_alloc(struct hnb_ue *ue)
+{
+	struct gtp_conn *conn;
+
+	conn = talloc_zero(ue, struct gtp_conn);
+	if (!conn)
+		return NULL;
+
+	conn->ue = ue;
+
+	llist_add(&conn->list, &ue->conn_ps.conn_list);
+
+	return conn;
+}
+
+void gtp_conn_free(struct gtp_conn *conn)
+{
+	if (!conn)
+		return;
+
+	if (conn->pdp_lib) {
+		pdp_freepdp(conn->pdp_lib);
+		conn->pdp_lib = NULL;
+	}
+	llist_del(&conn->list);
+	talloc_free(conn);
+}
+
 /* Get osa of locally bound GTP-U socket */
-int sk_get_bound_addr(int fd, struct osmo_sockaddr *osa)
+static int sk_get_bound_addr(int fd, struct osmo_sockaddr *osa)
 {
 	int rc;
 	socklen_t alen = sizeof(*osa);
@@ -44,18 +74,22 @@
 static int hnb_gtp_cb_data_ind(struct pdp_t *lib, void *packet, unsigned int len)
 {
 	struct hnb_gtp_prim *gtp_prim;
-	struct hnb_ue *ue = lib->priv;
-	struct hnb *hnb = ue->hnb;
+	struct gtp_conn *conn = lib->priv;
+	struct hnb_ue *ue;
+	struct hnb *hnb;
 	int rc;
 
-	if (!ue || !ue->conn_ps.active) {
-		LOGUE(ue, DGTP, LOGL_NOTICE, "Tx GTP-CONN_DATA.ind data=%p len=%u but UE conn_ps is not active!\n",
+	if (!conn || !conn->ue->conn_ps.active) {
+		LOGUE(conn->ue, DGTP, LOGL_NOTICE, "Tx GTP-CONN_DATA.ind data=%p len=%u but UE conn_ps is not active!\n",
 		      packet, len);
 		return -EINVAL;
 	}
 
+	ue = conn->ue;
+	hnb = ue->hnb;
+
 	LOGUE(ue, DGTP, LOGL_DEBUG, "Tx GTP-CONN_DATA.ind data=%p len=%u\n", packet, len);
-	gtp_prim = hnb_gtp_makeprim_conn_data_ind(ue->conn_id, ue->conn_ps.local_tei, packet, len);
+	gtp_prim = hnb_gtp_makeprim_conn_data_ind(conn->id, packet, len);
 	if ((rc = osmo_prim_srv_send(hnb->llsk, gtp_prim->hdr.msg)) < 0) {
 		LOGUE(ue, DGTP, LOGL_ERROR, "Failed Tx GTP-CONN_DATA.ind data=%p len=%u\n",
 		      packet, len);
@@ -129,10 +163,10 @@
 	hnb->gtp.fd1u.fd = -1;
 }
 
-int hnb_ue_gtp_bind(struct hnb_ue *ue, const struct osmo_sockaddr *rem_addr, uint32_t rem_tei,
-		     struct osmo_sockaddr *loc_addr, uint32_t *loc_tei)
+int gtp_conn_setup(struct gtp_conn *conn, const struct osmo_sockaddr *rem_addr, uint32_t rem_tei)
 {
 	int rc;
+	struct hnb_ue *ue = conn->ue;
 	struct hnb *hnb = ue->hnb;
 	struct pdp_t *pdp;
 	struct in_addr rem_in;
@@ -146,15 +180,18 @@
 		return -ENOTSUP;
 	}
 
+	conn->rem_addr = *rem_addr;
+	conn->rem_tei = rem_tei;
 	rem_in = rem_addr->u.sin.sin_addr;
+	conn->id = next_gtp_conn_id++; /* TODO: validate next one is not already taken due to wrap-around */
 
-	rc = gtp_pdp_newpdp(hnb->gtp.gsn, &pdp, ue->conn_id, 0 /* TODO: NSAPI? */, NULL);
+	rc = gtp_pdp_newpdp(hnb->gtp.gsn, &pdp, conn->id, 0 /* TODO: NSAPI? */, NULL);
 	if (rc < 0) {
 		LOGUE(ue, DGTP, LOGL_ERROR, "Failed creating PDP context: %s\n", strerror(-rc));
 		return rc;
 	}
-	pdp->priv = ue;
-	ue->conn_ps.pdp_lib = pdp;
+	pdp->priv = conn;
+	conn->pdp_lib = pdp;
 
 	pdp->teid_gn = rem_tei;
 	pdp->version = 1;
@@ -169,39 +206,32 @@
 	memcpy(pdp->gsnlu.v, &hnb->gtp.local_addr.u.sin.sin_addr,
 	       sizeof(hnb->gtp.local_addr.u.sin.sin_addr));
 
-	*loc_addr = hnb->gtp.local_addr;
+	conn->loc_addr = hnb->gtp.local_addr;
 	//loc_addr->u.sin.sin_family = AF_INET;
 	//loc_addr->u.sin.sin_addr = hnb->gtp.gsn->gsnu;
 	//loc_addr->u.sin.sin_port = GTP1U_PORT;
-	*loc_tei = pdp->teid_own;
+	conn->loc_tei = pdp->teid_own;
 	return 0;
 }
 
-int hnb_ue_gtp_tx(struct hnb_ue *ue, void *gtpu_payload, unsigned gtpu_payload_len)
+int gtp_conn_tx(struct gtp_conn *conn, void *gtpu_payload, unsigned gtpu_payload_len)
 {
 	int rc;
-	struct hnb *hnb = ue->hnb;
+	struct hnb_ue *ue;
+	struct hnb *hnb;
 
+	if (!conn || !conn->pdp_lib) {
+		LOGP(DGTP, LOGL_ERROR, "Tx: PDP Ctx not available\n");
+		return -EINVAL;
+	}
+
+	ue = conn->ue;
+	hnb = ue->hnb;
 	if (!hnb->gtp.gsn) {
 		LOGUE(ue, DGTP, LOGL_ERROR, "Tx: GTP socket not bound\n");
 		return -EINVAL;
 	}
 
-	if (!ue || !ue->conn_ps.pdp_lib) {
-		LOGUE(ue, DGTP, LOGL_ERROR, "Tx: UE PDP Ctx not available\n");
-		return -EINVAL;
-	}
-
-	rc = gtp_data_req(hnb->gtp.gsn, ue->conn_ps.pdp_lib, gtpu_payload, gtpu_payload_len);
+	rc = gtp_data_req(hnb->gtp.gsn, conn->pdp_lib, gtpu_payload, gtpu_payload_len);
 	return rc;
 }
-
-int hnb_ue_gtp_unbind(struct hnb_ue *ue)
-{
-	if (!ue->conn_ps.pdp_lib)
-		return -EINVAL;
-
-	pdp_freepdp(ue->conn_ps.pdp_lib);
-	ue->conn_ps.pdp_lib = NULL;
-	return 0;
-}
diff --git a/src/osmo-hnodeb/hnb.c b/src/osmo-hnodeb/hnb.c
index b733d15..fe2f4f5 100644
--- a/src/osmo-hnodeb/hnb.c
+++ b/src/osmo-hnodeb/hnb.c
@@ -109,6 +109,9 @@
 	ue->hnb = hnb;
 	ue->conn_id = conn_id;
 
+	INIT_LLIST_HEAD(&ue->conn_cs.conn_list);
+	INIT_LLIST_HEAD(&ue->conn_ps.conn_list);
+
 	llist_add(&ue->list, &hnb->ue_list);
 
 	return ue;
@@ -125,11 +128,17 @@
 void hnb_ue_reset_chan(struct hnb_ue *ue, bool is_ps)
 {
 	if (is_ps) {
-		hnb_ue_gtp_unbind(ue);
+		struct gtp_conn *conn, *conn_tmp;
+		llist_for_each_entry_safe(conn, conn_tmp, &ue->conn_ps.conn_list, list)
+			gtp_conn_free(conn);
 		ue->conn_ps = (struct hnb_ue_ps_ctx){0};
+		INIT_LLIST_HEAD(&ue->conn_ps.conn_list);
 	} else {
-		hnb_ue_voicecall_release(ue);
+		struct rtp_conn *conn, *conn_tmp;
+		llist_for_each_entry_safe(conn, conn_tmp, &ue->conn_cs.conn_list, list)
+			rtp_conn_free(conn);
 		ue->conn_cs = (struct hnb_ue_cs_ctx){0};
+		INIT_LLIST_HEAD(&ue->conn_cs.conn_list);
 	}
 }
 
@@ -145,21 +154,6 @@
 	return NULL;
 }
 
-struct hnb_ue *hnb_find_ue_by_tei(const struct hnb *hnb, uint32_t tei, bool is_remote)
-{
-	struct hnb_ue *ue;
-
-	llist_for_each_entry(ue, &hnb->ue_list, list) {
-		if (!ue->conn_ps.active)
-			continue;
-		uint32_t ue_tei = is_remote ? ue->conn_ps.remote_tei : ue->conn_ps.local_tei;
-		if (tei != ue_tei)
-			continue;
-		return ue;
-	}
-	return NULL;
-}
-
 struct hnb_ue *hnb_find_ue_by_imsi(const struct hnb *hnb, char *imsi)
 {
 	struct hnb_ue *ue;
@@ -176,3 +170,35 @@
 	}
 	return NULL;
 }
+
+struct rtp_conn *hnb_find_rtp_conn_by_id(const struct hnb *hnb, uint32_t audio_conn_id)
+{
+	struct hnb_ue *ue;
+
+	llist_for_each_entry(ue, &hnb->ue_list, list) {
+		struct rtp_conn *conn;
+		if (!ue->conn_cs.active)
+			continue;
+		llist_for_each_entry(conn, &ue->conn_cs.conn_list, list) {
+			if (conn->id == audio_conn_id)
+				return conn;
+		}
+	}
+	return NULL;
+}
+
+struct gtp_conn *hnb_find_gtp_conn_by_id(const struct hnb *hnb, uint32_t gtp_conn_id)
+{
+	struct hnb_ue *ue;
+
+	llist_for_each_entry(ue, &hnb->ue_list, list) {
+		struct gtp_conn *conn;
+		if (!ue->conn_ps.active)
+			continue;
+		llist_for_each_entry(conn, &ue->conn_ps.conn_list, list) {
+			if (conn->id == gtp_conn_id)
+				return conn;
+		}
+	}
+	return NULL;
+}
diff --git a/src/osmo-hnodeb/llsk_audio.c b/src/osmo-hnodeb/llsk_audio.c
index 4fa8079..7ce5c09 100644
--- a/src/osmo-hnodeb/llsk_audio.c
+++ b/src/osmo-hnodeb/llsk_audio.c
@@ -81,14 +81,16 @@
 	return (struct hnb_audio_prim *)oph;
 }
 
-static struct hnb_audio_prim *hnb_audio_makeprim_conn_establish_cnf(uint32_t context_id, uint8_t error_code,
-							     uint16_t local_rtp_port, uint8_t local_rtp_address_type,
-							     const union u_addr *local_rtp_addr)
+static struct hnb_audio_prim *hnb_audio_makeprim_conn_establish_cnf(uint32_t context_id, uint32_t audio_conn_id,
+								    uint8_t error_code, uint16_t local_rtp_port,
+								    uint8_t local_rtp_address_type,
+								    const union u_addr *local_rtp_addr)
 {
 	struct hnb_audio_prim *audio_prim;
 
 	audio_prim = hnb_audio_prim_alloc(HNB_AUDIO_PRIM_CONN_ESTABLISH, PRIM_OP_CONFIRM, 0);
 	audio_prim->u.conn_establish_cnf.context_id = context_id;
+	audio_prim->u.conn_establish_cnf.audio_conn_id = audio_conn_id;
 	audio_prim->u.conn_establish_cnf.local_rtp_port = local_rtp_port;
 	audio_prim->u.conn_establish_cnf.error_code = error_code;
 	audio_prim->u.conn_establish_cnf.local_rtp_address_type = local_rtp_address_type;
@@ -98,15 +100,14 @@
 	return audio_prim;
 }
 
-static struct hnb_audio_prim *hnb_audio_makeprim_conn_data_ind(uint32_t context_id,
-							uint8_t domain,
+static struct hnb_audio_prim *hnb_audio_makeprim_conn_data_ind(uint32_t audio_conn_id,
 							const uint8_t *data,
 							uint32_t data_len)
 {
 	struct hnb_audio_prim *audio_prim;
 
 	audio_prim = hnb_audio_prim_alloc(HNB_AUDIO_PRIM_CONN_DATA, PRIM_OP_INDICATION, data_len);
-	audio_prim->u.conn_data_ind.context_id = context_id;
+	audio_prim->u.conn_data_ind.audio_conn_id = audio_conn_id;
 	audio_prim->u.conn_data_ind.data_len = data_len;
 	if (data_len) {
 		msgb_put(audio_prim->hdr.msg, data_len);
@@ -116,15 +117,15 @@
 	return audio_prim;
 }
 
-int llsk_audio_tx_conn_data_ind(struct hnb_ue *ue, const uint8_t *payload, uint32_t len)
+int llsk_audio_tx_conn_data_ind(struct rtp_conn *conn, const uint8_t *payload, uint32_t len)
 {
 	struct hnb_audio_prim *audio_prim;
 	int rc;
 
-	LOGUE(ue, DLLSK, LOGL_INFO, "Tx AUDIO-CONN_DATA.ind\n");
-	audio_prim = hnb_audio_makeprim_conn_data_ind(ue->conn_id, 0 /* CS */, payload, len);
-	if ((rc = osmo_prim_srv_send(ue->hnb->llsk, audio_prim->hdr.msg)) < 0)
-		LOGUE(ue, DLLSK, LOGL_ERROR, "Failed sending AUDIO-CONN_DATA.ind\n");
+	LOGUE(conn->ue, DLLSK, LOGL_INFO, "Tx AUDIO-CONN_DATA.ind\n");
+	audio_prim = hnb_audio_makeprim_conn_data_ind(conn->id, payload, len);
+	if ((rc = osmo_prim_srv_send(conn->ue->hnb->llsk, audio_prim->hdr.msg)) < 0)
+		LOGUE(conn->ue, DLLSK, LOGL_ERROR, "Failed sending AUDIO-CONN_DATA.ind\n");
 	return rc;
 }
 
@@ -134,7 +135,7 @@
 	int rc;
 	LOGP(DLLSK, LOGL_ERROR, "Tx AUDIO-CONN_ESTABLISH.cnf: ctx=%u error_code=%u\n",
 	     context_id, error_code);
-	audio_prim = hnb_audio_makeprim_conn_establish_cnf(context_id, error_code, 0, HNB_PRIM_ADDR_TYPE_UNSPEC, NULL);
+	audio_prim = hnb_audio_makeprim_conn_establish_cnf(context_id, 0, error_code, 0, HNB_PRIM_ADDR_TYPE_UNSPEC, NULL);
 	if ((rc = osmo_prim_srv_send(hnb->llsk, audio_prim->hdr.msg)) < 0) {
 		LOGP(DLLSK, LOGL_ERROR, "Failed sending AUDIO-CONN_ESTABLISH.cnf context_id=%u error_code=%u\n",
 		     context_id, error_code);
@@ -150,9 +151,9 @@
 	int af;
 	char rem_addrstr[INET6_ADDRSTRLEN+32];
 	struct osmo_sockaddr rem_osa = {0};
-	struct osmo_sockaddr loc_osa = {0};
 	union u_addr loc_uaddr = {0};
 	uint16_t loc_port;
+	struct rtp_conn *conn = NULL;
 
 	rc = ll_addr2osa(ce_req->remote_rtp_address_type, &ce_req->remote_rtp_addr, ce_req->remote_rtp_port, &rem_osa);
 	if (rc < 0) {
@@ -184,14 +185,15 @@
 	}
 
 	/* Create the socket: */
-	if ((rc = hnb_ue_voicecall_setup(ue, &rem_osa, &loc_osa)) < 0) {
+	conn = rtp_conn_alloc(ue);
+	if ((rc = rtp_conn_setup(conn, &rem_osa)) < 0) {
 		LOGUE(ue, DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: Failed to set up audio socket rem_addr=%s\n",
 		      rem_addrstr);
 		return _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 4);
 	}
 
 	/* Convert resulting local address back to LLSK format: */
-	if (osa2_ll_addr(&loc_osa, &loc_uaddr,  &loc_port) != ce_req->remote_rtp_address_type) {
+	if (osa2_ll_addr(&conn->loc_addr, &loc_uaddr,  &loc_port) != ce_req->remote_rtp_address_type) {
 		LOGUE(ue, DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_ESTABLISH.req: Failed to provide proper local address rem_addr=%s\n",
 		      rem_addrstr);
 		rc = _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 4);
@@ -200,8 +202,8 @@
 
 	/* Submit successful confirmation */
 	LOGUE(ue, DLLSK, LOGL_INFO, "Tx AUDIO-CONN_ESTABLISH.cnf: error_code=0 rem_addr=%s loc_addr=%s\n",
-	      rem_addrstr, osmo_sockaddr_to_str(&loc_osa));
-	audio_prim = hnb_audio_makeprim_conn_establish_cnf(ce_req->context_id, 0, loc_port,
+	      rem_addrstr, osmo_sockaddr_to_str(&conn->loc_addr));
+	audio_prim = hnb_audio_makeprim_conn_establish_cnf(ce_req->context_id, conn->id, 0, loc_port,
 							   ce_req->remote_rtp_address_type, &loc_uaddr);
 	if ((rc = osmo_prim_srv_send(hnb->llsk, audio_prim->hdr.msg)) < 0) {
 		LOGUE(ue, DLLSK, LOGL_ERROR, "Failed sending AUDIO-CONN_ESTABLISH.cnf error_code=0\n");
@@ -210,47 +212,49 @@
 
 	return rc;
 release_sock:
-	hnb_ue_voicecall_release(ue);
+	rtp_conn_free(conn);
 	return rc;
 }
 
 static int llsk_rx_audio_conn_release_req(struct hnb *hnb, struct hnb_audio_conn_release_req_param *rel_req)
 {
-	struct hnb_ue *ue;
+	struct rtp_conn *conn;
 
-	LOGP(DLLSK, LOGL_DEBUG, "Rx AUDIO-CONN_RELEASE.req ctx=%u\n", rel_req->context_id);
+	LOGP(DLLSK, LOGL_DEBUG, "Rx AUDIO-CONN_RELEASE.req id=%u\n", rel_req->audio_conn_id);
 
-	ue = hnb_find_ue_by_id(hnb, rel_req->context_id);
-	if (!ue) {
-		LOGP(DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_RELEASE.req: UE not found! ctx=%u\n",
-		     rel_req->context_id);
+	conn = hnb_find_rtp_conn_by_id(hnb, rel_req->audio_conn_id);
+	if (!conn) {
+		LOGP(DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_RELEASE.req: RTP conn not found! id=%u\n",
+		     rel_req->audio_conn_id);
 		return -EINVAL;
 	}
 	/* Release RTP socket: */
-	return hnb_ue_voicecall_release(ue);
+	rtp_conn_free(conn);
+	return 0;
 }
 
 static int llsk_rx_audio_conn_data_req(struct hnb *hnb, struct hnb_audio_conn_data_req_param *data_req)
 {
-	struct hnb_ue *ue;
+	struct rtp_conn *conn;
 	int rc = 0;
 
-	LOGP(DLLSK, LOGL_DEBUG, "Rx AUDIO-CONN_DATA.req ctx=%u data_len=%u\n",
-	     data_req->context_id, data_req->data_len);
+	LOGP(DLLSK, LOGL_DEBUG, "Rx AUDIO-CONN_DATA.req id=%u data_len=%u\n",
+	     data_req->audio_conn_id, data_req->data_len);
 
-	ue = hnb_find_ue_by_id(hnb, data_req->context_id);
-	if (!ue) {
-		LOGP(DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_DATA.req: UE not found! ctx=%u data_len=%u\n",
-		     data_req->context_id, data_req->data_len);
+	conn = hnb_find_rtp_conn_by_id(hnb, data_req->audio_conn_id);
+	if (!conn) {
+		LOGP(DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_DATA.req: RTP conn not found! id=%u data_len=%u\n",
+		     data_req->audio_conn_id, data_req->data_len);
 		return -EINVAL;
 	}
 
 	/* TODO: transmit data_req->data through RTP/Iu-UP socket */
-	rc = osmo_rtp_send_frame_ext(ue->conn_cs.rtp.socket, data_req->data,
+	rc = osmo_rtp_send_frame_ext(conn->socket, data_req->data,
 				     data_req->data_len, GSM_RTP_DURATION, false);
 	if (rc < 0) {
-		LOGUE(ue, DLLSK, LOGL_ERROR, "Rx AUDIO-CONN_DATA.req: UE not found! ctx=%u data_len=%u\n",
-		     data_req->context_id, data_req->data_len);
+		LOGUE(conn->ue, DLLSK, LOGL_ERROR,
+		      "Rx AUDIO-CONN_DATA.req: Failed sending RTP frame! id=%u data_len=%u\n",
+		      data_req->audio_conn_id, data_req->data_len);
 	}
 	return rc;
 }
diff --git a/src/osmo-hnodeb/llsk_gtp.c b/src/osmo-hnodeb/llsk_gtp.c
index e75c497..30451a0 100644
--- a/src/osmo-hnodeb/llsk_gtp.c
+++ b/src/osmo-hnodeb/llsk_gtp.c
@@ -79,14 +79,16 @@
 	return (struct hnb_gtp_prim *)oph;
 }
 
-static struct hnb_gtp_prim *hnb_gtp_makeprim_conn_establish_cnf(uint32_t context_id, uint8_t error_code,
-								uint32_t local_tei, uint8_t local_gtpu_address_type,
+static struct hnb_gtp_prim *hnb_gtp_makeprim_conn_establish_cnf(uint32_t context_id, uint32_t gtp_conn_id,
+								uint8_t error_code, uint32_t local_tei,
+								uint8_t local_gtpu_address_type,
 								const union u_addr *local_gtpu_addr)
 {
 	struct hnb_gtp_prim *gtp_prim;
 
 	gtp_prim = hnb_gtp_prim_alloc(HNB_GTP_PRIM_CONN_ESTABLISH, PRIM_OP_CONFIRM, 0);
 	gtp_prim->u.conn_establish_cnf.context_id = context_id;
+	gtp_prim->u.conn_establish_cnf.gtp_conn_id = gtp_conn_id;
 	gtp_prim->u.conn_establish_cnf.local_tei = local_tei;
 	gtp_prim->u.conn_establish_cnf.error_code = error_code;
 	gtp_prim->u.conn_establish_cnf.local_gtpu_address_type = local_gtpu_address_type;
@@ -96,14 +98,12 @@
 	return gtp_prim;
 }
 
-struct hnb_gtp_prim *hnb_gtp_makeprim_conn_data_ind(uint32_t context_id, uint32_t local_tei,
-						    const uint8_t *data, uint32_t data_len)
+struct hnb_gtp_prim *hnb_gtp_makeprim_conn_data_ind(uint32_t gtp_conn_id, const uint8_t *data, uint32_t data_len)
 {
 	struct hnb_gtp_prim *gtp_prim;
 
 	gtp_prim = hnb_gtp_prim_alloc(HNB_GTP_PRIM_CONN_DATA, PRIM_OP_INDICATION, data_len);
-	gtp_prim->u.conn_data_ind.context_id = context_id;
-	gtp_prim->u.conn_data_ind.local_tei = local_tei;
+	gtp_prim->u.conn_data_ind.gtp_conn_id = gtp_conn_id;
 	gtp_prim->u.conn_data_ind.data_len = data_len;
 	if (data_len) {
 		msgb_put(gtp_prim->hdr.msg, data_len);
@@ -119,7 +119,7 @@
 	int rc;
 	LOGP(DLLSK, LOGL_ERROR, "Tx GTP-CONN_ESTABLISH.cnf: ctx=%u error_code=%u\n",
 	     context_id, error_code);
-	gtp_prim = hnb_gtp_makeprim_conn_establish_cnf(context_id, error_code, 0, HNB_PRIM_ADDR_TYPE_UNSPEC, NULL);
+	gtp_prim = hnb_gtp_makeprim_conn_establish_cnf(context_id, 0, error_code, 0, HNB_PRIM_ADDR_TYPE_UNSPEC, NULL);
 	if ((rc = osmo_prim_srv_send(hnb->llsk, gtp_prim->hdr.msg)) < 0) {
 		LOGP(DLLSK, LOGL_ERROR, "Failed sending GTP-CONN_ESTABLISH.cnf context_id=%u error_code=%u\n",
 		     context_id, error_code);
@@ -135,9 +135,8 @@
 	int af;
 	char rem_addrstr[INET6_ADDRSTRLEN+32];
 	struct osmo_sockaddr rem_osa = {0};
-	struct osmo_sockaddr loc_osa = {0};
 	union u_addr loc_uaddr = {0};
-	uint32_t loc_tei;
+	struct gtp_conn *conn = NULL;
 
 	rc = ll_addr2osa(ce_req->remote_gtpu_address_type, &ce_req->remote_gtpu_addr, GTP1U_PORT, &rem_osa);
 	if (rc < 0) {
@@ -169,14 +168,15 @@
 	}
 
 	/* Create the socket: */
-	if ((rc = hnb_ue_gtp_bind(ue, &rem_osa, ce_req->remote_tei, &loc_osa, &loc_tei)) < 0) {
+	conn = gtp_conn_alloc(ue);
+	if ((rc = gtp_conn_setup(conn, &rem_osa, ce_req->remote_tei)) < 0) {
 		LOGUE(ue, DLLSK, LOGL_ERROR, "Rx GTP-CONN_ESTABLISH.req: Failed to set up gtp socket rem_tei=%u rem_addr=%s\n",
 		     ce_req->remote_tei, rem_addrstr);
 		return _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 4);
 	}
 
 	/* Convert resulting local address back to LLSK format: */
-	if (osa2_ll_addr(&loc_osa, &loc_uaddr,  NULL) != ce_req->remote_gtpu_address_type) {
+	if (osa2_ll_addr(&conn->loc_addr, &loc_uaddr,  NULL) != ce_req->remote_gtpu_address_type) {
 		LOGUE(ue, DLLSK, LOGL_ERROR, "Rx GTP-CONN_ESTABLISH.req: Failed to provide proper local address rem_addr=%s\n",
 		      rem_addrstr);
 		rc = _send_conn_establish_cnf_failed(hnb, ce_req->context_id, 4);
@@ -185,56 +185,53 @@
 
 	/* Submit successful confirmation */
 	LOGUE(ue, DLLSK, LOGL_INFO, "Tx GTP-CONN_ESTABLISH.cnf: error_code=0 rem_addr=%s rem_tei=%u loc_addr=%s local_tei=%u\n",
-	     rem_addrstr, ce_req->remote_tei, osmo_sockaddr_to_str(&loc_osa), loc_tei);
-	gtp_prim = hnb_gtp_makeprim_conn_establish_cnf(ce_req->context_id, 0, loc_tei, ce_req->remote_gtpu_address_type, &loc_uaddr);
+	     rem_addrstr, ce_req->remote_tei, osmo_sockaddr_to_str(&conn->loc_addr), conn->loc_tei);
+	gtp_prim = hnb_gtp_makeprim_conn_establish_cnf(ce_req->context_id, conn->id, 0, conn->loc_tei,
+						       ce_req->remote_gtpu_address_type, &loc_uaddr);
 	if ((rc = osmo_prim_srv_send(hnb->llsk, gtp_prim->hdr.msg)) < 0) {
 		LOGUE(ue, DLLSK, LOGL_ERROR, "Failed sending GTP-CONN_ESTABLISH.cnf error_code=0\n");
 		goto release_sock;
 	}
-
-	ue->conn_ps.local_tei = loc_tei;
-	ue->conn_ps.remote_tei = ce_req->remote_tei;
-
 	return rc;
 release_sock:
-	hnb_ue_gtp_unbind(ue);
+	gtp_conn_free(conn);
 	return rc;
 }
 
 static int llsk_rx_gtp_conn_release_req(struct hnb *hnb, struct hnb_gtp_conn_release_req_param *rel_req)
 {
-	struct hnb_ue *ue;
+	struct gtp_conn *conn;
 	int rc = 0;
 
-	LOGP(DLLSK, LOGL_DEBUG, "Rx GTP-CONN_RELEASE.req ctx=%u\n", rel_req->context_id);
+	LOGP(DLLSK, LOGL_DEBUG, "Rx GTP-CONN_RELEASE.req id=%u\n", rel_req->gtp_conn_id);
 
-	ue = hnb_find_ue_by_id(hnb, rel_req->context_id);
-	if (!ue) {
-		LOGP(DLLSK, LOGL_ERROR, "Rx GTP-CONN_RELEASE.req: UE not found! ctx=%u\n",
-		     rel_req->context_id);
+	conn = hnb_find_gtp_conn_by_id(hnb, rel_req->gtp_conn_id);
+	if (!conn) {
+		LOGP(DLLSK, LOGL_ERROR, "Rx GTP-CONN_RELEASE.req: GTP conn not found! id=%u\n",
+		     rel_req->gtp_conn_id);
 		return -EINVAL;
 	}
 	/* release GTP pdp ctx: */
-	hnb_ue_gtp_unbind(ue);
+	gtp_conn_free(conn);
 	return rc;
 }
 
 static int llsk_rx_gtp_conn_data_req(struct hnb *hnb, struct hnb_gtp_conn_data_req_param *data_req)
 {
-	struct hnb_ue *ue;
+	struct gtp_conn *conn;
 	int rc = 0;
 
-	LOGP(DLLSK, LOGL_DEBUG, "Rx GTP-CONN_DATA.req ctx=%u rem_tei=%u data_len=%u\n",
-	     data_req->context_id, data_req->remote_tei, data_req->data_len);
+	LOGP(DLLSK, LOGL_DEBUG, "Rx GTP-CONN_DATA.req id=%u data_len=%u\n",
+	     data_req->gtp_conn_id, data_req->data_len);
 
-	ue = hnb_find_ue_by_id(hnb, data_req->context_id);
-	if (!ue) {
-		LOGP(DLLSK, LOGL_ERROR, "Rx GTP-CONN_DATA.req: UE not found! ctx=%u data_len=%u\n",
-		     data_req->context_id, data_req->data_len);
+	conn = hnb_find_gtp_conn_by_id(hnb, data_req->gtp_conn_id);
+	if (!conn) {
+		LOGP(DLLSK, LOGL_ERROR, "Rx GTP-CONN_DATA.req: GTP conn not found! id=%u data_len=%u\n",
+		     data_req->gtp_conn_id, data_req->data_len);
 		return -EINVAL;
 	}
 
-	rc = hnb_ue_gtp_tx(ue, data_req->data, data_req->data_len);
+	rc = gtp_conn_tx(conn, data_req->data, data_req->data_len);
 	return rc;
 }
 
diff --git a/src/osmo-hnodeb/rtp.c b/src/osmo-hnodeb/rtp.c
index cc03c6c..2f40d99 100644
--- a/src/osmo-hnodeb/rtp.c
+++ b/src/osmo-hnodeb/rtp.c
@@ -27,6 +27,33 @@
 #include <osmocom/hnodeb/rtp.h>
 #include <osmocom/hnodeb/hnodeb.h>
 
+struct rtp_conn *rtp_conn_alloc(struct hnb_ue *ue)
+{
+	struct rtp_conn *conn;
+
+	conn = talloc_zero(ue, struct rtp_conn);
+	if (!conn)
+		return NULL;
+
+	conn->ue = ue;
+
+	llist_add(&conn->list, &ue->conn_cs.conn_list);
+
+	return conn;
+}
+
+void rtp_conn_free(struct rtp_conn *conn)
+{
+	if (!conn)
+		return;
+
+	if (conn->socket) {
+		osmo_rtp_socket_free(conn->socket);
+		conn->socket = NULL;
+	}
+	llist_del(&conn->list);
+	talloc_free(conn);
+}
 
 /* Mixture between osmo_rtp_get_bound_addr and osmo_rtp_get_bound_ip_port using osmo_sockaddr */
 /*static int rtp_get_bound_addr(struct osmo_rtp_socket *rs, struct osmo_sockaddr *osa)
@@ -97,11 +124,13 @@
 
 	tries = (hnb->rtp.port_range_end - hnb->rtp.port_range_start) / 2;
 	for (i = 0; i < tries; i++) {
+		uint16_t port;
 
 		if (hnb->rtp.port_range_next >= hnb->rtp.port_range_end)
 			hnb->rtp.port_range_next = hnb->rtp.port_range_start;
 
-		rc = osmo_rtp_socket_bind(rs, ip, hnb->rtp.port_range_next);
+		port = hnb->rtp.port_range_next;
+		rc = osmo_rtp_socket_bind(rs, ip, port);
 
 		hnb->rtp.port_range_next += 2;
 
@@ -118,7 +147,7 @@
 				LOGP(DRTP, LOGL_ERROR, "failed to set socket priority %d: %s\n",
 					hnb->rtp.priority, strerror(errno));
 		}
-		return 0;
+		return port;
 	}
 
 	return -1;
@@ -128,14 +157,14 @@
 	       unsigned int rtp_pl_len, uint16_t seq_number,
 	       uint32_t timestamp, bool marker)
 {
-	struct hnb_ue *ue = (struct hnb_ue *)rs->priv;
+	struct rtp_conn *conn = (struct rtp_conn *)rs->priv;
 
-	LOGUE(ue, DRTP, LOGL_DEBUG, "Rx RTP seq=%u ts=%u M=%u pl=%p len=%u\n",
+	LOGUE(conn->ue, DRTP, LOGL_DEBUG, "Rx RTP seq=%u ts=%u M=%u pl=%p len=%u\n",
 	      seq_number, timestamp, marker, rtp_pl, rtp_pl_len);
-	llsk_audio_tx_conn_data_ind(ue, rtp_pl, rtp_pl_len);
+	llsk_audio_tx_conn_data_ind(conn, rtp_pl, rtp_pl_len);
 }
 
-int hnb_ue_voicecall_setup(struct hnb_ue *ue, const struct osmo_sockaddr *rem_addr, struct osmo_sockaddr *loc_addr)
+int rtp_conn_setup(struct rtp_conn *conn, const struct osmo_sockaddr *rem_addr)
 {
 	int rc;
 	char cname[256+4];
@@ -144,6 +173,7 @@
 	const char *local_wildcard_ipstr = "0.0.0.0";
 	char remote_ipstr[INET6_ADDRSTRLEN];
 	uint16_t remote_port;
+	struct hnb_ue *ue = conn->ue;
 	struct hnb *hnb = ue->hnb;
 
 	if (osmo_sockaddr_to_str_and_uint(remote_ipstr, sizeof(remote_ipstr), &remote_port, &rem_addr->u.sa) == 0) {
@@ -151,12 +181,9 @@
 		return -EINVAL;
 	}
 
-	if (ue->conn_cs.rtp.socket) {
-		LOGUE(ue, DRTP, LOGL_ERROR, "Setting up rtp socket but it already exists!\n");
-		return -EINVAL;
-	}
+	conn->rem_addr = *rem_addr;
 
-	rs = ue->conn_cs.rtp.socket = osmo_rtp_socket_create(ue, 0);
+	rs = conn->socket = osmo_rtp_socket_create(ue, 0);
 	rc = osmo_rtp_socket_set_param(rs,
 				       hnb->rtp.jitter_adaptive ?
 				       OSMO_RTP_P_JIT_ADAP :
@@ -166,7 +193,7 @@
 		LOGUE(ue, DRTP, LOGL_ERROR, "Failed to set RTP socket parameters: %s\n", strerror(-rc));
 		goto free_ret;
 	}
-	rs->priv = ue;
+	rs->priv = conn;
 	rs->rx_cb = &rtp_rx_cb;
 
 	rc = rtp_bind(hnb, rs, local_wildcard_ipstr);
@@ -174,10 +201,11 @@
 		LOGUE(ue, DRTP, LOGL_ERROR, "Failed to bind RTP/RTCP sockets\n");
 		goto free_ret;
 	}
+	conn->id = rc; /* We use local port as rtp conn ID */
 
 	/* Ensure RTCP SDES contains some useful information */
 	snprintf(cname, sizeof(cname), "hnb@%s", local_wildcard_ipstr);
-	snprintf(name, sizeof(name), "ue@%u", ue->conn_id);
+	snprintf(name, sizeof(name), "ue@%u-%u", conn->ue->conn_id, conn->id);
 	osmo_rtp_set_source_desc(rs, cname, name, NULL, NULL, NULL,
 				 "OsmoHNodeB-" PACKAGE_VERSION, NULL);
 
@@ -188,8 +216,8 @@
 	}
 
 	/* osmo_rtp_socket_connect() is broken, OS#5356 */
-	//rc = rtp_get_bound_addr(rs, loc_addr);
-	rc = rtp_get_bound_addr(rs, rem_addr, loc_addr);
+	//rc = rtp_get_bound_addr(rs, &conn->loc_addr);
+	rc = rtp_get_bound_addr(rs, rem_addr, &conn->loc_addr);
 	if (rc < 0) {
 		LOGUE(ue, DRTP, LOGL_ERROR, "Cannot obtain locally bound IP/port: %d\n", rc);
 		goto free_ret;
@@ -197,16 +225,7 @@
 
 	return rc;
 free_ret:
-	osmo_rtp_socket_free(ue->conn_cs.rtp.socket);
-	ue->conn_cs.rtp.socket = NULL;
+	osmo_rtp_socket_free(conn->socket);
+	conn->socket = NULL;
 	return rc;
 }
-
-int hnb_ue_voicecall_release(struct hnb_ue *ue)
-{
-	if (!ue->conn_cs.rtp.socket)
-		return -EINVAL;
-	osmo_rtp_socket_free(ue->conn_cs.rtp.socket);
-	ue->conn_cs.rtp.socket = NULL;
-	return 0;
-}

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-hnodeb/+/26570
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-hnodeb
Gerrit-Branch: master
Gerrit-Change-Id: Ib3f60d5ba21defe5259c25e2034fc2217c4d93df
Gerrit-Change-Number: 26570
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20211214/28a26ddc/attachment.htm>


More information about the gerrit-log mailing list