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