diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2022-08-11 14:59:36 +0200 |
---|---|---|
committer | Pau Espin Pedrol <pespin@sysmocom.de> | 2022-08-11 21:02:06 +0200 |
commit | 5a1b14fa4f5f3dbaf386fd3d1c942ba22c14f9ad (patch) | |
tree | 87f1035d8fed575ffb9b4efb24cbe3f4f2b64879 | |
parent | d9f2cf2df632f3fe01f654b74e929b05c288d7e6 (diff) |
Split out lchan rtp socket creation from rsl handling code
This makes the code more clear, as well as allows adding Osmux in the
future.
Change-Id: Iade43fde7f6113f9d68539f7d6cc9843783c2b3f
-rw-r--r-- | include/osmo-bts/lchan.h | 5 | ||||
-rw-r--r-- | src/common/lchan.c | 135 | ||||
-rw-r--r-- | src/common/rsl.c | 116 |
3 files changed, 143 insertions, 113 deletions
diff --git a/include/osmo-bts/lchan.h b/include/osmo-bts/lchan.h index 90c28d97..c86acb0a 100644 --- a/include/osmo-bts/lchan.h +++ b/include/osmo-bts/lchan.h @@ -2,6 +2,7 @@ #include <stdbool.h> #include <stdint.h> +#include <netinet/in.h> #include <osmocom/core/timer.h> #include <osmocom/core/linuxlist.h> @@ -354,6 +355,10 @@ int lchan2ecu_codec(const struct gsm_lchan *lchan); void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state); +int lchan_rtp_socket_create(struct gsm_lchan *lchan, const char *bind_ip); +int lchan_rtp_socket_connect(struct gsm_lchan *lchan, const struct in_addr *ia, uint16_t connect_port); +void lchan_rtp_socket_free(struct gsm_lchan *lchan); + static inline bool lchan_is_dcch(const struct gsm_lchan *lchan) { switch (lchan->type) { diff --git a/src/common/lchan.c b/src/common/lchan.c index fe5efd57..6f344e2b 100644 --- a/src/common/lchan.c +++ b/src/common/lchan.c @@ -19,6 +19,8 @@ * */ +#include "btsconfig.h" /* for PACKAGE_VERSION */ + #include <osmocom/core/logging.h> #include <osmocom/trau/osmo_ortp.h> @@ -200,9 +202,7 @@ void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind rsl_tx_ipac_dlcx_ind(lchan, RSL_ERR_NORMAL_UNSPEC); osmo_rtp_socket_log_stats(lchan->abis_ip.rtp_socket, DRTP, LOGL_INFO, "Closing RTP socket on Channel Release "); - osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); - lchan->abis_ip.rtp_socket = NULL; - msgb_queue_flush(&lchan->dl_tch_queue); + lchan_rtp_socket_free(lchan); } /* FIXME: right now we allow creating the rtp_socket even if chan is not @@ -510,3 +510,132 @@ int lchan2ecu_codec(const struct gsm_lchan *lchan) return -1; } } + +static int bind_rtp(struct gsm_bts *bts, struct osmo_rtp_socket *rs, const char *ip) +{ + int rc; + unsigned int i; + unsigned int tries; + + tries = (bts->rtp_port_range_end - bts->rtp_port_range_start) / 2; + for (i = 0; i < tries; i++) { + + if (bts->rtp_port_range_next >= bts->rtp_port_range_end) + bts->rtp_port_range_next = bts->rtp_port_range_start; + + rc = osmo_rtp_socket_bind(rs, ip, bts->rtp_port_range_next); + + bts->rtp_port_range_next += 2; + + if (rc != 0) + continue; + + if (bts->rtp_ip_dscp != -1) { + if (osmo_rtp_socket_set_dscp(rs, bts->rtp_ip_dscp)) + LOGP(DRSL, LOGL_ERROR, "failed to set DSCP=%d: %s\n", + bts->rtp_ip_dscp, strerror(errno)); + } + if (bts->rtp_priority != -1) { + if (osmo_rtp_socket_set_priority(rs, bts->rtp_priority)) + LOGP(DRSL, LOGL_ERROR, "failed to set socket priority %d: %s\n", + bts->rtp_priority, strerror(errno)); + } + return 0; + } + + return -1; +} + +int lchan_rtp_socket_create(struct gsm_lchan *lchan, const char *bind_ip) +{ + struct gsm_bts *bts = lchan->ts->trx->bts; + char cname[256+4]; + int rc; + + if (lchan->abis_ip.rtp_socket) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC CRCX, " + "but we already have socket!\n"); + return -EALREADY; + } + + /* FIXME: select default value depending on speech_mode */ + //if (!payload_type) + lchan->tch.last_fn = LCHAN_FN_DUMMY; + lchan->abis_ip.rtp_socket = osmo_rtp_socket_create(lchan->ts->trx, + OSMO_RTP_F_POLL); + + if (!lchan->abis_ip.rtp_socket) { + LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to create RTP/RTCP sockets\n"); + oml_tx_failure_event_rep(&lchan->ts->trx->mo, + NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT, + "%s IPAC Failed to create RTP/RTCP sockets", + gsm_lchan_name(lchan)); + return -ENOTCONN; + } + + rc = osmo_rtp_socket_set_param(lchan->abis_ip.rtp_socket, + bts->rtp_jitter_adaptive ? + OSMO_RTP_P_JIT_ADAP : + OSMO_RTP_P_JITBUF, + bts->rtp_jitter_buf_ms); + if (rc < 0) + LOGPLCHAN(lchan, DRTP, LOGL_ERROR, + "IPAC Failed to set RTP socket parameters: %s\n", strerror(-rc)); + else + LOGPLCHAN(lchan, DRTP, LOGL_INFO, "IPAC set RTP socket parameters: %d\n", rc); + + lchan->abis_ip.rtp_socket->priv = lchan; + lchan->abis_ip.rtp_socket->rx_cb = &l1sap_rtp_rx_cb; + + rc = bind_rtp(bts, lchan->abis_ip.rtp_socket, bind_ip); + if (rc < 0) { + LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to bind RTP/RTCP sockets\n"); + oml_tx_failure_event_rep(&lchan->ts->trx->mo, + NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT, + "%s IPAC Failed to bind RTP/RTCP sockets", + gsm_lchan_name(lchan)); + lchan_rtp_socket_free(lchan); + return -EBADFD; + } + + /* Ensure RTCP SDES contains some useful information */ + snprintf(cname, sizeof(cname), "bts@%s", bind_ip); + osmo_rtp_set_source_desc(lchan->abis_ip.rtp_socket, cname, + gsm_lchan_name(lchan), NULL, NULL, + gsm_trx_unit_id(lchan->ts->trx), + "OsmoBTS-" PACKAGE_VERSION, NULL); + /* FIXME: multiplex connection, BSC proxy */ + return 0; +} + + +int lchan_rtp_socket_connect(struct gsm_lchan *lchan, const struct in_addr *ia, uint16_t connect_port) +{ + int bound_port = 0; + int rc; + + rc = osmo_rtp_socket_connect(lchan->abis_ip.rtp_socket, + inet_ntoa(*ia), connect_port); + if (rc < 0) { + LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "Failed to connect RTP/RTCP sockets\n"); + return -ECONNREFUSED; + } + /* save IP address and port number */ + lchan->abis_ip.connect_ip = ntohl(ia->s_addr); + lchan->abis_ip.connect_port = connect_port; + + rc = osmo_rtp_get_bound_ip_port(lchan->abis_ip.rtp_socket, + &lchan->abis_ip.bound_ip, + &bound_port); + if (rc < 0) + LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC cannot obtain locally bound IP/port: %d\n", rc); + lchan->abis_ip.bound_port = bound_port; + return 0; +} + +void lchan_rtp_socket_free(struct gsm_lchan *lchan) +{ + osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); + lchan->abis_ip.rtp_socket = NULL; + msgb_queue_flush(&lchan->dl_tch_queue); +} diff --git a/src/common/rsl.c b/src/common/rsl.c index e8765a77..bcbe27c4 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -21,8 +21,6 @@ * */ -#include "btsconfig.h" /* for PACKAGE_VERSION */ - #include <stdio.h> #include <errno.h> #include <netdb.h> @@ -2706,51 +2704,15 @@ static char *get_rsl_local_ip(struct gsm_bts_trx *trx) return hostbuf; } -static int bind_rtp(struct gsm_bts *bts, struct osmo_rtp_socket *rs, const char *ip) -{ - int rc; - unsigned int i; - unsigned int tries; - - tries = (bts->rtp_port_range_end - bts->rtp_port_range_start) / 2; - for (i = 0; i < tries; i++) { - - if (bts->rtp_port_range_next >= bts->rtp_port_range_end) - bts->rtp_port_range_next = bts->rtp_port_range_start; - - rc = osmo_rtp_socket_bind(rs, ip, bts->rtp_port_range_next); - - bts->rtp_port_range_next += 2; - - if (rc != 0) - continue; - - if (bts->rtp_ip_dscp != -1) { - if (osmo_rtp_socket_set_dscp(rs, bts->rtp_ip_dscp)) - LOGP(DRSL, LOGL_ERROR, "failed to set DSCP=%i: %s\n", - bts->rtp_ip_dscp, strerror(errno)); - } - if (bts->rtp_priority != -1) { - if (osmo_rtp_socket_set_priority(rs, bts->rtp_priority)) - LOGP(DRSL, LOGL_ERROR, "failed to set socket priority %d: %s\n", - bts->rtp_priority, strerror(errno)); - } - return 0; - } - - return -1; -} - static int rsl_rx_ipac_XXcx(struct msgb *msg) { struct abis_rsl_dchan_hdr *dch = msgb_l2(msg); struct tlv_parsed tp; struct gsm_lchan *lchan = msg->lchan; - struct gsm_bts *bts = lchan->ts->trx->bts; const uint8_t *payload_type, *speech_mode, *payload_type2; uint32_t connect_ip = 0; uint16_t connect_port = 0; - int rc, inc_ip_port = 0, port; + int rc, inc_ip_port = 0; char *name; struct in_addr ia; struct in_addr addr; @@ -2807,41 +2769,7 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg) } if (dch->c.msg_type == RSL_MT_IPAC_CRCX) { - char cname[256+4]; char *ipstr = NULL; - if (lchan->abis_ip.rtp_socket) { - LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC CRCX, " - "but we already have socket!\n"); - return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, - inc_ip_port, dch->c.msg_type); - } - /* FIXME: select default value depending on speech_mode */ - //if (!payload_type) - lchan->tch.last_fn = LCHAN_FN_DUMMY; - lchan->abis_ip.rtp_socket = osmo_rtp_socket_create(lchan->ts->trx, - OSMO_RTP_F_POLL); - if (!lchan->abis_ip.rtp_socket) { - LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to create RTP/RTCP sockets\n"); - oml_tx_failure_event_rep(&lchan->ts->trx->mo, - NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT, - "%s IPAC Failed to create RTP/RTCP sockets", - gsm_lchan_name(lchan)); - return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, - inc_ip_port, dch->c.msg_type); - } - rc = osmo_rtp_socket_set_param(lchan->abis_ip.rtp_socket, - bts->rtp_jitter_adaptive ? - OSMO_RTP_P_JIT_ADAP : - OSMO_RTP_P_JITBUF, - bts->rtp_jitter_buf_ms); - if (rc < 0) - LOGPLCHAN(lchan, DRTP, LOGL_ERROR, - "IPAC Failed to set RTP socket parameters: %s\n", strerror(-rc)); - else - LOGPLCHAN(lchan, DRTP, LOGL_INFO, "IPAC set RTP socket parameters: %d\n", rc); - lchan->abis_ip.rtp_socket->priv = lchan; - lchan->abis_ip.rtp_socket->rx_cb = &l1sap_rtp_rx_cb; - if (connect_ip && connect_port) { /* if CRCX specifies a remote IP, we can bind() * here to 0.0.0.0 and wait for the connect() @@ -2856,26 +2784,10 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg) * back to the BSC in the CRCX_ACK */ ipstr = get_rsl_local_ip(lchan->ts->trx); } - rc = bind_rtp(bts, lchan->abis_ip.rtp_socket, ipstr); - if (rc < 0) { - LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to bind RTP/RTCP sockets\n"); - oml_tx_failure_event_rep(&lchan->ts->trx->mo, - NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT, - "%s IPAC Failed to bind RTP/RTCP sockets", - gsm_lchan_name(lchan)); - osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); - lchan->abis_ip.rtp_socket = NULL; - msgb_queue_flush(&lchan->dl_tch_queue); + rc = lchan_rtp_socket_create(lchan, ipstr); + if (rc < 0) return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, inc_ip_port, dch->c.msg_type); - } - /* Ensure RTCP SDES contains some useful information */ - snprintf(cname, sizeof(cname), "bts@%s", ipstr); - osmo_rtp_set_source_desc(lchan->abis_ip.rtp_socket, cname, - gsm_lchan_name(lchan), NULL, NULL, - gsm_trx_unit_id(lchan->ts->trx), - "OsmoBTS-" PACKAGE_VERSION, NULL); - /* FIXME: multiplex connection, BSC proxy */ } else { /* MDCX */ if (!lchan->abis_ip.rtp_socket) { @@ -2896,26 +2808,12 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg) ia.s_addr = htonl(get_signlink_remote_ip(sign_link)); } else ia.s_addr = connect_ip; - rc = osmo_rtp_socket_connect(lchan->abis_ip.rtp_socket, - inet_ntoa(ia), connect_port); + rc = lchan_rtp_socket_connect(lchan, &ia, connect_port); if (rc < 0) { - LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "Failed to connect RTP/RTCP sockets\n"); - osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); - lchan->abis_ip.rtp_socket = NULL; - msgb_queue_flush(&lchan->dl_tch_queue); + lchan_rtp_socket_free(lchan); return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, inc_ip_port, dch->c.msg_type); } - /* save IP address and port number */ - lchan->abis_ip.connect_ip = ntohl(ia.s_addr); - lchan->abis_ip.connect_port = connect_port; - - rc = osmo_rtp_get_bound_ip_port(lchan->abis_ip.rtp_socket, - &lchan->abis_ip.bound_ip, - &port); - if (rc < 0) - LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC cannot obtain locally bound IP/port: %d\n", rc); - lchan->abis_ip.bound_port = port; /* Everything has succeeded, we can store new values in lchan */ if (payload_type) { @@ -2957,9 +2855,7 @@ static int rsl_rx_ipac_dlcx(struct msgb *msg) if (lchan->abis_ip.rtp_socket) { osmo_rtp_socket_log_stats(lchan->abis_ip.rtp_socket, DRTP, LOGL_INFO, "Closing RTP socket on DLCX "); - osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); - lchan->abis_ip.rtp_socket = NULL; - msgb_queue_flush(&lchan->dl_tch_queue); + lchan_rtp_socket_free(lchan); } return rc; } |