From 7550ba3d052b81b0653ca141ef456da8931c5788 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Tue, 14 Dec 2021 18:19:13 +0100 Subject: [PATCH] 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 --- doc/hnodeb.msc | 10 ++-- include/osmocom/hnodeb/gtp.h | 24 ++++++++-- include/osmocom/hnodeb/hnb_prim.h | 23 ++++----- include/osmocom/hnodeb/hnodeb.h | 15 ++---- include/osmocom/hnodeb/llsk.h | 7 ++- include/osmocom/hnodeb/rtp.h | 16 ++++++- src/osmo-hnodeb/gtp.c | 79 +++++++++++++++++++++---------- src/osmo-hnodeb/hnb.c | 60 ++++++++++++++++------- src/osmo-hnodeb/llsk_audio.c | 74 +++++++++++++++-------------- src/osmo-hnodeb/llsk_gtp.c | 63 ++++++++++++------------ src/osmo-hnodeb/rtp.c | 71 +++++++++++++++++---------- 11 files changed, 265 insertions(+), 177 deletions(-) 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 @@ msc { --- [ 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 @@ msc { 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 +#include + #include +#include struct hnb; struct hnb_ue; @@ -26,7 +30,19 @@ struct hnb_ue; 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 @@ struct hnb_audio_conn_establish_req_param { /* 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 @@ struct hnb_audio_conn_establish_cnf_param { /* 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 @@ struct hnb_gtp_conn_establish_req_param { /* 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 @@ struct hnb_gtp_conn_establish_cnf_param { /* 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 #include -#include -#include - #include enum { @@ -62,16 +59,12 @@ struct hnb_ue { 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 { 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 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 @@ struct hnb_iuh_prim *hnb_iuh_makeprim_unitdata_ind(const uint8_t *data, uint32_t 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 +#include 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 b8bfebc..22d4074 100644 --- a/src/osmo-hnodeb/gtp.c +++ b/src/osmo-hnodeb/gtp.c @@ -27,8 +27,38 @@ #include #include +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,19 +74,21 @@ int sk_get_bound_addr(int fd, struct osmo_sockaddr *osa) 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 gtp_conn *conn = lib->priv; + struct hnb_ue *ue; struct hnb *hnb; int rc; - if (!ue || !ue->conn_ps.active) { - LOGP(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); @@ -130,10 +162,10 @@ void hnb_gtp_unbind(struct hnb *hnb) 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; @@ -147,15 +179,18 @@ int hnb_ue_gtp_bind(struct hnb_ue *ue, const struct osmo_sockaddr *rem_addr, uin 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; @@ -170,40 +205,32 @@ int hnb_ue_gtp_bind(struct hnb_ue *ue, const struct osmo_sockaddr *rem_addr, uin 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_ue *ue; struct hnb *hnb; - if (!ue || !ue->conn_ps.pdp_lib) { - LOGUE(ue, DGTP, LOGL_ERROR, "Tx: UE PDP Ctx not available\n"); + 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; } - 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 @@ struct hnb_ue *hnb_ue_alloc(struct hnb *hnb, uint32_t conn_id) 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_free(struct hnb_ue *ue) 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 @@ struct hnb_ue *hnb_find_ue_by_id(const struct hnb *hnb, uint32_t conn_id) 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 @@ struct hnb_ue *hnb_find_ue_by_imsi(const struct hnb *hnb, char *imsi) } 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 @@ static struct hnb_audio_prim *hnb_audio_prim_alloc(enum hnb_audio_prim_type ptyp 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 @@ static struct hnb_audio_prim *hnb_audio_makeprim_conn_establish_cnf(uint32_t con 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 @@ static struct hnb_audio_prim *hnb_audio_makeprim_conn_data_ind(uint32_t context_ 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 @@ static int _send_conn_establish_cnf_failed(struct hnb *hnb, uint32_t context_id, 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 @@ static int llsk_rx_audio_conn_establish_req(struct hnb *hnb, struct hnb_audio_co 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 @@ static int llsk_rx_audio_conn_establish_req(struct hnb *hnb, struct hnb_audio_co } /* 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 @@ static int llsk_rx_audio_conn_establish_req(struct hnb *hnb, struct hnb_audio_co /* 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 @@ static int llsk_rx_audio_conn_establish_req(struct hnb *hnb, struct hnb_audio_co 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 @@ static struct hnb_gtp_prim *hnb_gtp_prim_alloc(enum hnb_gtp_prim_type ptype, enu 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 @@ static struct hnb_gtp_prim *hnb_gtp_makeprim_conn_establish_cnf(uint32_t context 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 @@ static int _send_conn_establish_cnf_failed(struct hnb *hnb, uint32_t context_id, 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 @@ static int llsk_rx_gtp_conn_establish_req(struct hnb *hnb, struct hnb_gtp_conn_e 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 @@ static int llsk_rx_gtp_conn_establish_req(struct hnb *hnb, struct hnb_gtp_conn_e } /* 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 @@ static int llsk_rx_gtp_conn_establish_req(struct hnb *hnb, struct hnb_gtp_conn_e /* 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 #include +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 @@ static int rtp_bind(struct hnb *hnb, struct osmo_rtp_socket *rs, const char *ip) 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 @@ static int rtp_bind(struct hnb *hnb, struct osmo_rtp_socket *rs, const char *ip) 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 @@ static void rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, 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 @@ int hnb_ue_voicecall_setup(struct hnb_ue *ue, const struct osmo_sockaddr *rem_ad 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 @@ int hnb_ue_voicecall_setup(struct hnb_ue *ue, const struct osmo_sockaddr *rem_ad 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 @@ int hnb_ue_voicecall_setup(struct hnb_ue *ue, const struct osmo_sockaddr *rem_ad 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 @@ int hnb_ue_voicecall_setup(struct hnb_ue *ue, const struct osmo_sockaddr *rem_ad 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 @@ int hnb_ue_voicecall_setup(struct hnb_ue *ue, const struct osmo_sockaddr *rem_ad } /* 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 @@ int hnb_ue_voicecall_setup(struct hnb_ue *ue, const struct osmo_sockaddr *rem_ad 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; -}